diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs index 1f8da845072..4814ae3f2de 100644 --- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs @@ -27,6 +27,9 @@ public sealed partial class ShaperProcessingExpressionVisitor : ExpressionVisito private static readonly bool UseOldBehavior35212 = AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35212", out var enabled35212) && enabled35212; + private static readonly bool UseOldBehavior36464 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue36464", out var enabled36464) && enabled36464; + /// /// Reading database values /// @@ -103,6 +106,9 @@ private static readonly PropertyInfo Utf8JsonReaderTokenTypeProperty private static readonly MethodInfo PropertyGetTypeMappingMethod = typeof(IReadOnlyProperty).GetMethod(nameof(IReadOnlyProperty.GetTypeMapping), [])!; + private static readonly PropertyInfo QueryContextQueryLoggerProperty = + typeof(QueryContext).GetProperty(nameof(QueryContext.QueryLogger))!; + private readonly RelationalShapedQueryCompilingExpressionVisitor _parentVisitor; private readonly ISet? _tags; private readonly bool _isTracking; @@ -1928,11 +1934,13 @@ protected override Expression VisitSwitch(SwitchExpression switchExpression) New( JsonReaderManagerConstructor, jsonReaderDataParameter, - liftableConstantFactory.CreateLiftableConstant( - queryLogger, - static c => c.Dependencies.QueryLogger, - "queryLogger", - typeof(IDiagnosticsLogger)))), + UseOldBehavior36464 + ? liftableConstantFactory.CreateLiftableConstant( + queryLogger, + static c => c.Dependencies.QueryLogger, + "queryLogger", + typeof(IDiagnosticsLogger)) + : MakeMemberAccess(QueryCompilationContext.QueryContextParameter, QueryContextQueryLoggerProperty))), // tokenType = jsonReaderManager.CurrentReader.TokenType Assign( tokenTypeVariable, @@ -2113,11 +2121,13 @@ void ProcessFixup(IDictionary fixupMap) New( JsonReaderManagerConstructor, jsonReaderDataParameter, - liftableConstantFactory.CreateLiftableConstant( - queryLogger, - static c => c.Dependencies.QueryLogger, - "queryLogger", - typeof(IDiagnosticsLogger)))); + UseOldBehavior36464 + ? liftableConstantFactory.CreateLiftableConstant( + queryLogger, + static c => c.Dependencies.QueryLogger, + "queryLogger", + typeof(IDiagnosticsLogger)) + : MakeMemberAccess(QueryCompilationContext.QueryContextParameter, QueryContextQueryLoggerProperty))); readExpressions.Add( Block( @@ -2472,11 +2482,13 @@ private bool IsPropertyAssignment( New( JsonReaderManagerConstructor, jsonReaderDataVariable, - _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( - _queryLogger, - static c => c.Dependencies.QueryLogger, - "queryLogger", - typeof(IDiagnosticsLogger)))), + UseOldBehavior36464 + ? _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( + _queryLogger, + static c => c.Dependencies.QueryLogger, + "queryLogger", + typeof(IDiagnosticsLogger)) + : MakeMemberAccess(QueryCompilationContext.QueryContextParameter, QueryContextQueryLoggerProperty))), Call(jsonReaderManagerVariable, Utf8JsonReaderManagerMoveNextMethod), Call(jsonReaderManagerVariable, Utf8JsonReaderManagerCaptureStateMethod))); @@ -2849,7 +2861,7 @@ Expression valueExpression // UPDATE: instead of guessing the type mapping in case where we don't have IProperty and converter uses non-literal constant, // we just revert to the pre-AOT behavior, i.e. we still use converter.ConvertFromProviderExpression // this will not work for precompiled query (which realistically was already broken for this scenario - type mapping we "guess" - // is pretty much always wrong), but regular case (not pre-compiled) will continue to work. + // is pretty much always wrong), but regular case (not pre-compiled) will continue to work. if (property != null) { var typeMappingExpression = Call(