From 53dbe80437c29fe342c3b671dbaf2125029ef213 Mon Sep 17 00:00:00 2001 From: Maurycy Markowski Date: Tue, 23 Jan 2018 19:14:01 -0800 Subject: [PATCH] Fix to 10733 - Query: we inject redundant MaterializeCollectionNavigation calls into some queries that take advantage of correlated collection optimizations Removing MaterializeCollectionNavigation call if we apply correlated collection optimizations inside. CorrelateCollection method already materializes the collection so there is no need to do it second time. --- .../CorrelatedCollectionOptimizingVisitor.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/EFCore/Query/ExpressionVisitors/Internal/CorrelatedCollectionOptimizingVisitor.cs b/src/EFCore/Query/ExpressionVisitors/Internal/CorrelatedCollectionOptimizingVisitor.cs index 1bdea4fc355..13316ef3ee2 100644 --- a/src/EFCore/Query/ExpressionVisitors/Internal/CorrelatedCollectionOptimizingVisitor.cs +++ b/src/EFCore/Query/ExpressionVisitors/Internal/CorrelatedCollectionOptimizingVisitor.cs @@ -71,6 +71,34 @@ public CorrelatedCollectionOptimizingVisitor( /// public virtual IReadOnlyList ParentOrderings => _parentOrderings.AsReadOnly(); + /// + /// This API supports the Entity Framework Core infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression) + { + if (methodCallExpression.Method.MethodIsClosedFormOf(CollectionNavigationSubqueryInjector.MaterializeCollectionNavigationMethodInfo) + && methodCallExpression.Arguments[1] is SubQueryExpression subQueryExpression) + { + if (_queryCompilationContext.CorrelatedSubqueryMetadataMap.TryGetValue(subQueryExpression.QueryModel.MainFromClause, out var correlatedSubqueryMetadata)) + { + var parentQsre = new QuerySourceReferenceExpression(correlatedSubqueryMetadata.ParentQuerySource); + var result = Rewrite( + correlatedSubqueryMetadata.Index, + subQueryExpression.QueryModel, + correlatedSubqueryMetadata.CollectionNavigation, + correlatedSubqueryMetadata.TrackingQuery, + parentQsre); + + return result; + } + + return methodCallExpression; + } + + return base.VisitMethodCall(methodCallExpression); + } + /// /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases.