From e15a3a4bbc3b528c54b390a2adfd48d335dfc2d2 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Fri, 12 Sep 2025 23:48:16 +0200 Subject: [PATCH] Resolve query logger from QueryContext in shaper generation (#36758) Instead of closing over the current scoped logger, causing a leak. Closes #36464 (cherry picked from commit b7996bea1566d1afd3f8c0fe9226b6c3c6b19d32) --- ...sitor.ShaperProcessingExpressionVisitor.cs | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs index d65ceaa0269..de2e8969612 100644 --- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs @@ -19,6 +19,9 @@ private sealed partial class ShaperProcessingExpressionVisitor : ExpressionVisit public static readonly bool UseOldBehavior32310 = AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue32310", out var enabled32310) && enabled32310; + private static readonly bool UseOldBehavior36464 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue36464", out var enabled36464) && enabled36464; + /// /// Reading database values /// @@ -80,6 +83,9 @@ private static readonly MethodInfo Utf8JsonReaderGetStringMethod private static readonly MethodInfo EnumParseMethodInfo = typeof(Enum).GetMethod(nameof(Enum.Parse), new[] { typeof(Type), typeof(string) })!; + private static readonly PropertyInfo QueryContextQueryLoggerProperty = + typeof(QueryContext).GetProperty(nameof(QueryContext.QueryLogger))!; + private readonly RelationalShapedQueryCompilingExpressionVisitor _parentVisitor; private readonly ISet? _tags; private readonly bool _isTracking; @@ -1644,7 +1650,9 @@ protected override Expression VisitSwitch(SwitchExpression switchExpression) New( JsonReaderManagerConstructor, _jsonReaderDataParameter, - Constant(_queryLogger))), + UseOldBehavior36464 + ? Constant(_queryLogger) + : MakeMemberAccess(QueryCompilationContext.QueryContextParameter, QueryContextQueryLoggerProperty))), // tokenType = jsonReaderManager.CurrentReader.TokenType Assign( tokenTypeVariable, @@ -1807,7 +1815,13 @@ void ProcessFixup(IDictionary fixupMap) var captureState = Call(managerVariable, Utf8JsonReaderManagerCaptureStateMethod); var assignment = Assign(propertyVariable, innerShaperMapElement.Value); var managerRecreation = Assign( - managerVariable, New(JsonReaderManagerConstructor, _jsonReaderDataParameter, Constant(_queryLogger))); + managerVariable, + New( + JsonReaderManagerConstructor, + _jsonReaderDataParameter, + UseOldBehavior36464 + ? Constant(_queryLogger) + : MakeMemberAccess(QueryCompilationContext.QueryContextParameter, QueryContextQueryLoggerProperty))); readExpressions.Add( Block( @@ -2170,7 +2184,13 @@ private static IList PopulateList(IList buffer, IList target) Default(typeof(JsonReaderData))), Block( Assign( - jsonReaderManagerVariable, New(JsonReaderManagerConstructor, jsonReaderDataVariable, Constant(_queryLogger))), + jsonReaderManagerVariable, + New( + JsonReaderManagerConstructor, + jsonReaderDataVariable, + UseOldBehavior36464 + ? Constant(_queryLogger) + : MakeMemberAccess(QueryCompilationContext.QueryContextParameter, QueryContextQueryLoggerProperty))), Call(jsonReaderManagerVariable, Utf8JsonReaderManagerMoveNextMethod), Call(jsonReaderManagerVariable, Utf8JsonReaderManagerCaptureStateMethod)));