66using System . Linq . Expressions ;
77using System . Reflection ;
88using System . Runtime . CompilerServices ;
9+ using LinqToDB . Common . Internal ;
910using Microsoft . EntityFrameworkCore ;
1011using Microsoft . EntityFrameworkCore . Diagnostics ;
1112using Microsoft . EntityFrameworkCore . Infrastructure ;
@@ -39,17 +40,19 @@ internal sealed class EFCoreMetadataReader : IMetadataReader
3940 private readonly IRelationalAnnotationProvider ? _annotationProvider ;
4041 private readonly ConcurrentDictionary < MemberInfo , EFCoreExpressionAttribute ? > _calculatedExtensions = new ( ) ;
4142 private readonly IDiagnosticsLogger < DbLoggerCategory . Query > ? _logger ;
43+ private readonly DatabaseDependencies ? _databaseDependencies ;
4244
4345 public EFCoreMetadataReader ( IModel ? model , IInfrastructure < IServiceProvider > ? accessor )
4446 {
4547 _model = model ;
4648
4749 if ( accessor != null )
4850 {
49- _dependencies = accessor . GetService < RelationalSqlTranslatingExpressionVisitorDependencies > ( ) ;
50- _mappingSource = accessor . GetService < IRelationalTypeMappingSource > ( ) ;
51- _annotationProvider = accessor . GetService < IRelationalAnnotationProvider > ( ) ;
52- _logger = accessor . GetService < IDiagnosticsLogger < DbLoggerCategory . Query > > ( ) ;
51+ _dependencies = accessor . GetService < RelationalSqlTranslatingExpressionVisitorDependencies > ( ) ;
52+ _mappingSource = accessor . GetService < IRelationalTypeMappingSource > ( ) ;
53+ _annotationProvider = accessor . GetService < IRelationalAnnotationProvider > ( ) ;
54+ _logger = accessor . GetService < IDiagnosticsLogger < DbLoggerCategory . Query > > ( ) ;
55+ _databaseDependencies = accessor . GetService < DatabaseDependencies > ( ) ;
5356 }
5457
5558 _objectId = $ ".{ _model ? . GetHashCode ( ) ?? 0 } .{ _dependencies ? . GetHashCode ( ) ?? 0 } .{ _mappingSource ? . GetHashCode ( ) ?? 0 } .{ _annotationProvider ? . GetHashCode ( ) ?? 0 } .{ _logger ? . GetHashCode ( ) ?? 0 } .";
@@ -124,10 +127,10 @@ public MappingAttribute[] GetAttributes(Type type)
124127 // TableAttribute
125128 var tableAttribute = type . GetAttribute < System . ComponentModel . DataAnnotations . Schema . TableAttribute > ( ) ;
126129 if ( tableAttribute != null )
127- ( result ?? = new ( ) ) . Add ( new TableAttribute ( tableAttribute . Name ) { Schema = tableAttribute . Schema } ) ;
130+ ( result = new ( ) ) . Add ( new TableAttribute ( tableAttribute . Name ) { Schema = tableAttribute . Schema } ) ;
128131 }
129132
130- return result == null ? Array . Empty < MappingAttribute > ( ) : result . ToArray ( ) ;
133+ return result == null ? [ ] : result . ToArray ( ) ;
131134 }
132135
133136 static IEntityType GetBaseTypeRecursive ( IEntityType entityType )
@@ -137,7 +140,7 @@ static IEntityType GetBaseTypeRecursive(IEntityType entityType)
137140 return GetBaseTypeRecursive ( entityType . BaseType ) ;
138141 }
139142
140- static IEnumerable < InheritanceMappingAttribute > GetMappingAttributesRecursive ( IEntityType entityType )
143+ static List < InheritanceMappingAttribute > GetMappingAttributesRecursive ( IEntityType entityType )
141144 {
142145 var mappings = new List < InheritanceMappingAttribute > ( ) ;
143146 return ProcessEntityType ( entityType ) ;
@@ -221,7 +224,7 @@ static DataType DbTypeToDataType(DbType dbType)
221224 public MappingAttribute [ ] GetAttributes ( Type type , MemberInfo memberInfo )
222225 {
223226 if ( typeof ( Expression ) . IsSameOrParentOf ( type ) )
224- return Array . Empty < MappingAttribute > ( ) ;
227+ return [ ] ;
225228
226229 List < MappingAttribute > ? result = null ;
227230 var hasColumn = false ;
@@ -258,14 +261,30 @@ public MappingAttribute[] GetAttributes(Type type, MemberInfo memberInfo)
258261
259262 var storeObjectId = GetStoreObjectIdentifier ( et ) ;
260263
264+ var isIdentity = false ;
261265 var annotations = prop . GetAnnotations ( ) ;
262266 if ( _annotationProvider != null && storeObjectId != null )
263267 {
264268 if ( prop . FindColumn ( storeObjectId . Value ) is IColumn column )
265269 annotations = annotations . Concat ( _annotationProvider . For ( column , false ) ) ;
270+
271+ if ( _annotationProvider . GetType ( ) . Name == "SqliteAnnotationProvider" )
272+ {
273+ // copy-paste logic, not available anymore in v8
274+ // https://github.com/dotnet/efcore/blob/release/8.0/src/EFCore.Sqlite.Core/Metadata/Internal/SqliteAnnotationProvider.cs#L70-L75
275+ var primaryKey = prop . DeclaringType . ContainingEntityType . FindPrimaryKey ( ) ;
276+ if ( primaryKey is { Properties . Count : 1 }
277+ && primaryKey . Properties [ 0 ] == prop
278+ && prop . ValueGenerated == ValueGenerated . OnAdd
279+ && prop . ClrType . IsInteger ( )
280+ && prop . FindTypeMapping ( ) ? . Converter == null )
281+ {
282+ isIdentity = true ;
283+ }
284+ }
266285 }
267286
268- var isIdentity = annotations
287+ isIdentity = isIdentity || annotations
269288 . Any ( static a =>
270289 {
271290 if ( a . Name . EndsWith ( ":ValueGenerationStrategy" ) )
@@ -279,7 +298,7 @@ public MappingAttribute[] GetAttributes(Type type, MemberInfo memberInfo)
279298 {
280299 if ( a . Value is string str )
281300 {
282- return str . ToLowerInvariant ( ) . Contains ( "nextval" ) ;
301+ return str . Contains ( "nextval" , StringComparison . InvariantCultureIgnoreCase ) ;
283302 }
284303 }
285304
@@ -301,15 +320,15 @@ public MappingAttribute[] GetAttributes(Type type, MemberInfo memberInfo)
301320 }
302321 }
303322
304- var behaviour = prop . GetBeforeSaveBehavior ( ) ;
323+ var behavior = prop . GetBeforeSaveBehavior ( ) ;
305324 var skipOnInsert = prop . ValueGenerated . HasFlag ( ValueGenerated . OnAdd ) ;
306325
307326 if ( skipOnInsert )
308327 {
309- skipOnInsert = isIdentity || behaviour != PropertySaveBehavior . Save ;
328+ skipOnInsert = isIdentity || behavior != PropertySaveBehavior . Save ;
310329 }
311330
312- var skipOnUpdate = behaviour != PropertySaveBehavior . Save ||
331+ var skipOnUpdate = behavior != PropertySaveBehavior . Save ||
313332 prop . ValueGenerated . HasFlag ( ValueGenerated . OnUpdate ) ;
314333
315334 var ca = new ColumnAttribute ( )
@@ -432,7 +451,7 @@ public MappingAttribute[] GetAttributes(Type type, MemberInfo memberInfo)
432451 } ) ;
433452 }
434453
435- return result == null ? Array . Empty < MappingAttribute > ( ) : result . ToArray ( ) ;
454+ return result == null ? [ ] : result . ToArray ( ) ;
436455 }
437456
438457 sealed class ValueConverter : IValueConverter
@@ -462,7 +481,7 @@ public SqlTransparentExpression(Expression expression, RelationalTypeMapping? ty
462481
463482 protected override void Print ( ExpressionPrinter expressionPrinter )
464483 {
465- expressionPrinter . Print ( Expression ) ;
484+ expressionPrinter . PrintExpression ( Expression ) ;
466485 }
467486
468487 private bool Equals ( SqlTransparentExpression other )
@@ -493,7 +512,7 @@ public override int GetHashCode()
493512 } ;
494513 }
495514
496- private Sql . ExpressionAttribute ? GetDbFunctionFromMethodCall ( Type type , MethodInfo methodInfo )
515+ private EFCoreExpressionAttribute ? GetDbFunctionFromMethodCall ( Type type , MethodInfo methodInfo )
497516 {
498517 if ( _dependencies == null || _model == null )
499518 return null ;
@@ -516,8 +535,20 @@ public override int GetHashCode()
516535 var p = parameterInfos [ i ] ;
517536
518537 parametersArray [ i ] = new SqlTransparentExpression (
519- Expression . Constant ( DefaultValue . GetValue ( p . ParameterType ) , p . ParameterType ) ,
520- ctx . this_ . _mappingSource ? . FindMapping ( p . ParameterType ) ) ;
538+ Expression . Constant ( DefaultValue . GetValue ( p . ParameterType ) , p . ParameterType ) ,
539+ ctx . this_ . _mappingSource ? . FindMapping ( p . ParameterType ) ) ;
540+ }
541+
542+ // https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/issues/1801
543+ if ( ctx . this_ . _dependencies ! . MethodCallTranslatorProvider . GetType ( ) . Name == "MySqlMethodCallTranslatorProvider" )
544+ {
545+ var contextProperty = ctx . this_ . _dependencies ! . MethodCallTranslatorProvider . GetType ( ) . GetProperty ( "QueryCompilationContext" )
546+ ?? throw new InvalidOperationException ( "MySqlMethodCallTranslatorProvider.QueryCompilationContext property not found" ) ;
547+
548+ if ( contextProperty . GetValue ( ctx . this_ . _dependencies ! . MethodCallTranslatorProvider ) == null )
549+ {
550+ contextProperty . SetValue ( ctx . this_ . _dependencies ! . MethodCallTranslatorProvider , ctx . this_ . _databaseDependencies ! . QueryCompilationContextFactory . Create ( false ) ) ;
551+ }
521552 }
522553
523554 var newExpression = ctx . this_ . _dependencies ! . MethodCallTranslatorProvider . Translate ( ctx . this_ . _model ! , objExpr , ctx . methodInfo , parametersArray , ctx . this_ . _logger ! ) ;
@@ -536,7 +567,7 @@ public override int GetHashCode()
536567 return found ;
537568 }
538569
539- private Sql . ExpressionAttribute ? GetDbFunctionFromProperty ( Type type , PropertyInfo propInfo )
570+ private EFCoreExpressionAttribute ? GetDbFunctionFromProperty ( Type type , PropertyInfo propInfo )
540571 {
541572 if ( _dependencies == null || _model == null )
542573 return null ;
@@ -629,7 +660,7 @@ string PrepareExpressionText(Expression? expr)
629660 // https://github.com/npgsql/efcore.pg/blob/main/src/EFCore.PG/Query/Expressions/Internal/PostgresBinaryExpression.cs
630661 if ( newExpression . GetType ( ) . Name == "PostgresBinaryExpression" )
631662 {
632- // Handling NpgSql's PostgresBinaryExpression
663+ // Handling Npgsql PostgresBinaryExpression
633664
634665 var left = ( Expression ) newExpression . GetType ( ) . GetProperty ( "Left" ) ! . GetValue ( newExpression ) ! ;
635666 var right = ( Expression ) newExpression . GetType ( ) . GetProperty ( "Right" ) ! . GetValue ( newExpression ) ! ;
@@ -714,7 +745,7 @@ private static Expression UnwrapConverted(Expression expr)
714745
715746 public MemberInfo [ ] GetDynamicColumns ( Type type )
716747 {
717- return Array . Empty < MemberInfo > ( ) ;
748+ return [ ] ;
718749 }
719750
720751 string IMetadataReader . GetObjectID ( ) => _objectId ;
0 commit comments