44using System . Linq ;
55using System . Linq . Expressions ;
66using System . Reflection ;
7- using LinqToDB . Common ;
8- using LinqToDB . EntityFrameworkCore . Internal ;
9- using LinqToDB . SqlQuery ;
107using Microsoft . EntityFrameworkCore ;
11- using Microsoft . EntityFrameworkCore . Internal ;
128using Microsoft . EntityFrameworkCore . Metadata ;
13- using Microsoft . EntityFrameworkCore . Metadata . Conventions . Internal ;
149using Microsoft . EntityFrameworkCore . Metadata . Internal ;
15- using Microsoft . EntityFrameworkCore . Query . Expressions ;
16- using Microsoft . EntityFrameworkCore . Query . ExpressionVisitors ;
10+ using Microsoft . EntityFrameworkCore . Query ;
11+ using Microsoft . EntityFrameworkCore . Query . SqlExpressions ;
12+ using Microsoft . EntityFrameworkCore . Storage ;
1713
1814namespace LinqToDB . EntityFrameworkCore
1915{
2016 using Mapping ;
2117 using Metadata ;
2218 using Extensions ;
19+ using Common ;
20+ using Internal ;
21+ using SqlQuery ;
22+ using SqlExpression = Microsoft . EntityFrameworkCore . Query . SqlExpressions . SqlExpression ;
2323
2424 /// <summary>
2525 /// LINQ To DB metadata reader for EF.Core model.
2626 /// </summary>
2727 internal class EFCoreMetadataReader : IMetadataReader
2828 {
2929 readonly IModel _model ;
30- private readonly SqlTranslatingExpressionVisitorDependencies _dependencies ;
30+ private readonly RelationalSqlTranslatingExpressionVisitorDependencies _dependencies ;
31+ private readonly IRelationalTypeMappingSource _mappingSource ;
3132 private readonly ConcurrentDictionary < MemberInfo , EFCoreExpressionAttribute > _calculatedExtensions = new ConcurrentDictionary < MemberInfo , EFCoreExpressionAttribute > ( ) ;
3233
33- public EFCoreMetadataReader ( IModel model , SqlTranslatingExpressionVisitorDependencies dependencies )
34+ public EFCoreMetadataReader ( IModel model , RelationalSqlTranslatingExpressionVisitorDependencies dependencies , IRelationalTypeMappingSource mappingSource )
3435 {
3536 _model = model ;
3637 _dependencies = dependencies ;
38+ _mappingSource = mappingSource ;
3739 }
3840
3941 public T [ ] GetAttributes < T > ( Type type , bool inherit = true ) where T : Attribute
@@ -43,8 +45,7 @@ public T[] GetAttributes<T>(Type type, bool inherit = true) where T : Attribute
4345 {
4446 if ( typeof ( T ) == typeof ( TableAttribute ) )
4547 {
46- var relational = et . Relational ( ) ;
47- return new [ ] { ( T ) ( Attribute ) new TableAttribute ( relational . TableName ) { Schema = relational . Schema } } ;
48+ return new [ ] { ( T ) ( Attribute ) new TableAttribute ( et . GetTableName ( ) ) { Schema = et . GetSchema ( ) } } ;
4849 }
4950 }
5051
@@ -76,19 +77,17 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
7677 var primaryKeyOrder = 0 ;
7778 if ( isPrimaryKey )
7879 {
79- var pk = prop . GetContainingPrimaryKey ( ) ;
80+ var pk = prop . FindContainingPrimaryKey ( ) ;
8081 primaryKeyOrder = pk . Properties . Select ( ( p , i ) => new { p , index = i } )
8182 . FirstOrDefault ( v => v . p . GetIdentifyingMemberInfo ( ) == memberInfo ) ? . index ?? 0 ;
8283 }
8384
84- var relational = prop . Relational ( ) ;
85-
8685 return new T [ ] { ( T ) ( Attribute ) new ColumnAttribute
8786 {
88- Name = relational . ColumnName ,
87+ Name = prop . GetColumnName ( ) ,
8988 Length = prop . GetMaxLength ( ) ?? 0 ,
9089 CanBeNull = prop . IsNullable ,
91- DbType = relational . ColumnType ,
90+ DbType = prop . GetColumnType ( ) ,
9291 IsPrimaryKey = isPrimaryKey ,
9392 PrimaryKeyOrder = primaryKeyOrder ,
9493 IsIdentity = prop . ValueGenerated == ValueGenerated . OnAdd ,
@@ -170,21 +169,21 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
170169 {
171170 var method = ( MethodInfo ) memberInfo ;
172171
173- var func = _model ? . Relational ( ) . DbFunctions . FirstOrDefault ( f => f . MethodInfo == method ) ;
172+ var func = _model ? . GetDbFunctions ( ) . FirstOrDefault ( f => f . MethodInfo == method ) ;
174173 if ( func != null )
175174 return new T [ ]
176175 {
177176 ( T ) ( Attribute ) new Sql . FunctionAttribute
178177 {
179- Name = func . FunctionName ,
178+ Name = func . Name ,
180179 ServerSideOnly = true
181180 }
182181 } ;
183182
184183 var functionAttributes = memberInfo . GetCustomAttributes < DbFunctionAttribute > ( inherit ) ;
185184 return functionAttributes . Select ( f => ( T ) ( Attribute ) new Sql . FunctionAttribute
186185 {
187- Name = f . FunctionName ,
186+ Name = f . Name ,
188187 ServerSideOnly = true ,
189188 } ) . ToArray ( ) ;
190189 }
@@ -193,6 +192,21 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
193192 return Array . Empty < T > ( ) ;
194193 }
195194
195+ class SqlTransparentExpression : SqlExpression
196+ {
197+ public Expression Expression { get ; }
198+
199+ public SqlTransparentExpression ( Expression expression , RelationalTypeMapping typeMapping ) : base ( expression . Type , typeMapping )
200+ {
201+ Expression = expression ;
202+ }
203+
204+ public override void Print ( ExpressionPrinter expressionPrinter )
205+ {
206+ expressionPrinter . Print ( Expression ) ;
207+ }
208+ }
209+
196210 private Sql . ExpressionAttribute GetDbFunctionFromMethodCall ( Type type , MethodInfo methodInfo )
197211 {
198212 if ( _dependencies == null || _model == null )
@@ -206,19 +220,19 @@ private Sql.ExpressionAttribute GetDbFunctionFromMethodCall(Type type, MethodInf
206220
207221 if ( ! methodInfo . IsGenericMethodDefinition && ! mi . GetCustomAttributes < Sql . ExpressionAttribute > ( ) . Any ( ) )
208222 {
209- var objExpr = Expression . Constant ( DefaultValue . GetValue ( type ) , type ) ;
223+ var objExpr = new SqlTransparentExpression ( Expression . Constant ( DefaultValue . GetValue ( type ) , type ) , _mappingSource . FindMapping ( type ) ) ;
210224 var parameterInfos = methodInfo . GetParameters ( ) ;
211225 var parametersArray = parameterInfos
212226 . Select ( p =>
213- ( Expression ) Expression . Constant ( DefaultValue . GetValue ( p . ParameterType ) , p . ParameterType ) ) . ToArray ( ) ;
214-
215- var mcExpr = Expression . Call ( methodInfo . IsStatic ? null : objExpr , methodInfo , parametersArray ) ;
227+ ( SqlExpression ) new SqlTransparentExpression (
228+ Expression . Constant ( DefaultValue . GetValue ( p . ParameterType ) , p . ParameterType ) ,
229+ _mappingSource . FindMapping ( p . ParameterType ) ) ) . ToArray ( ) ;
216230
217- var newExpression = _dependencies . MethodCallTranslator . Translate ( mcExpr , _model ) ;
218- if ( newExpression != null && newExpression != mcExpr )
231+ var newExpression = _dependencies . MethodCallTranslatorProvider . Translate ( _model , objExpr , methodInfo , parametersArray ) ;
232+ if ( newExpression != null )
219233 {
220234 if ( ! methodInfo . IsStatic )
221- parametersArray = new Expression [ ] { objExpr } . Concat ( parametersArray ) . ToArray ( ) ;
235+ parametersArray = new SqlExpression [ ] { objExpr } . Concat ( parametersArray ) . ToArray ( ) ;
222236
223237 result = ConvertToExpressionAttribute ( methodInfo , newExpression , parametersArray ) ;
224238 }
@@ -243,11 +257,10 @@ private Sql.ExpressionAttribute GetDbFunctionFromProperty(Type type, PropertyInf
243257
244258 if ( ( propInfo . GetMethod ? . IsStatic != true ) && ! mi . GetCustomAttributes < Sql . ExpressionAttribute > ( ) . Any ( ) )
245259 {
246- var objExpr = Expression . Constant ( DefaultValue . GetValue ( type ) , type ) ;
247- var mcExpr = Expression . MakeMemberAccess ( objExpr , propInfo ) ;
260+ var objExpr = new SqlTransparentExpression ( Expression . Constant ( DefaultValue . GetValue ( type ) , type ) , _mappingSource . FindMapping ( propInfo ) ) ;
248261
249- var newExpression = _dependencies . MemberTranslator . Translate ( mcExpr ) ;
250- if ( newExpression != null && newExpression != mcExpr )
262+ var newExpression = _dependencies . MemberTranslatorProvider . Translate ( objExpr , propInfo , propInfo . GetMemberType ( ) ) ;
263+ if ( newExpression != null )
251264 {
252265 var parametersArray = new Expression [ ] { objExpr } ;
253266 result = ConvertToExpressionAttribute ( propInfo , newExpression , parametersArray ) ;
@@ -264,7 +277,7 @@ private static EFCoreExpressionAttribute ConvertToExpressionAttribute(MemberInfo
264277 {
265278 string PrepareExpressionText ( Expression expr )
266279 {
267- var idx = parameters . IndexOf ( expr ) ;
280+ var idx = Array . IndexOf ( parameters , expr ) ;
268281 if ( idx >= 0 )
269282 return $ "{{{idx}}}";
270283
@@ -273,9 +286,9 @@ string PrepareExpressionText(Expression expr)
273286
274287 if ( expr is SqlFunctionExpression sqlFunction )
275288 {
276- var text = sqlFunction . FunctionName ;
289+ var text = sqlFunction . Name ;
277290 if ( ! sqlFunction . Schema . IsNullOrEmpty ( ) )
278- text = sqlFunction . Schema + "." + sqlFunction . FunctionName ;
291+ text = sqlFunction . Schema + "." + sqlFunction . Name ;
279292
280293 if ( ! sqlFunction . IsNiladic )
281294 {
@@ -328,7 +341,7 @@ private static Expression UnwrapConverted(Expression expr)
328341 {
329342 if ( expr is SqlFunctionExpression func )
330343 {
331- if ( string . Equals ( func . FunctionName , "COALESCE" , StringComparison . InvariantCultureIgnoreCase ) &&
344+ if ( string . Equals ( func . Name , "COALESCE" , StringComparison . InvariantCultureIgnoreCase ) &&
332345 func . Arguments . Count == 2 && func . Arguments [ 1 ] . NodeType == ExpressionType . Default )
333346 return UnwrapConverted ( func . Arguments [ 0 ] ) ;
334347 }
0 commit comments