private void TryMarkSubQuery(SubQueryExpression expression) { var subQueryModel = expression.QueryModel; subQueryModel.SelectClause.TransformExpressions(Visit); if (CorrelatedSubqueryOptimizationValidator.CanTryOptimizeCorrelatedSubquery(subQueryModel)) { // if the query passes validation it becomes a candidate for future optimization // optimization can't always be performed, e.g. when client-eval is needed // but we need to collect metadata (i.e. INavigations) before nav rewrite converts them into joins _queryModelVisitor.BindNavigationPathPropertyExpression( subQueryModel.MainFromClause.FromExpression, (properties, querySource) => { var collectionNavigation = properties.OfType <INavigation>().SingleOrDefault(n => n.IsCollection()); if (collectionNavigation != null) { _queryModelVisitor.QueryCompilationContext.RegisterCorrelatedSubqueryMetadata( subQueryModel.MainFromClause, _trackingQuery, properties.OfType <INavigation>().First(), collectionNavigation, querySource); return(expression); } return(default); });
/// <summary> /// 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. /// </summary> protected override Expression VisitMember(MemberExpression memberExpression) { Check.NotNull(memberExpression, nameof(memberExpression)); var newMemberExpression = default(Expression); if (_shouldInject) { newMemberExpression = _queryModelVisitor.BindNavigationPathPropertyExpression( memberExpression, (properties, querySource) => { var collectionNavigation = properties.OfType <INavigation>().SingleOrDefault(n => n.IsCollection()); return(collectionNavigation != null ? InjectSubquery(memberExpression, collectionNavigation) : default(Expression)); }); } return(newMemberExpression ?? base.VisitMember(memberExpression)); }
protected override Expression VisitMember(MemberExpression node) { Check.NotNull(node, nameof(node)); return (_queryModelVisitor.BindNavigationPathPropertyExpression( node, (properties, querySource) => { var navigations = properties.OfType <INavigation>().ToList(); var collectionNavigation = navigations.SingleOrDefault(n => n.IsCollection()); return collectionNavigation != null ? InjectSubquery(node, collectionNavigation) : default(Expression); }) ?? base.VisitMember(node)); }
/// <summary> /// 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. /// </summary> protected override Expression VisitMember(MemberExpression node) => _queryModelVisitor.BindNavigationPathPropertyExpression( node, (ps, qs) => RewritePropertyAccess(node, ps, qs)) ?? base.VisitMember(node);