public override EntityQueryModelVisitor Create(
     QueryCompilationContext queryCompilationContext,
     EntityQueryModelVisitor parentEntityQueryModelVisitor)
     => new RelationalQueryModelVisitor(
         Model,
         QueryOptimizer,
         NavigationRewritingExpressionVisitorFactory,
         SubQueryMemberPushDownExpressionVisitor,
         QuerySourceTracingExpressionVisitorFactory,
         EntityResultFindingExpressionVisitorFactory,
         TaskBlockingExpressionVisitor,
         MemberAccessBindingExpressionVisitorFactory,
         OrderingExpressionVisitorFactory,
         ProjectionExpressionVisitorFactory,
         EntityQueryableExpressionVisitorFactory,
         QueryAnnotationExtractor,
         ResultOperatorHandler,
         EntityMaterializerSource,
         ExpressionPrinter,
         RelationalAnnotationProvider,
         IncludeExpressionVisitorFactory,
         SqlTranslatingExpressionVisitorFactory,
         CompositePredicateExpressionVisitorFactory,
         QueryFlatteningExpressionVisitorFactory,
         ShapedQueryFindingExpressionVisitorFactory,
         ContextOptions,
         (RelationalQueryCompilationContext)Check.NotNull(queryCompilationContext, nameof(queryCompilationContext)),
         (RelationalQueryModelVisitor)parentEntityQueryModelVisitor);
        public EntityTrackingInfo(
            [NotNull] IEntityKeyFactorySource entityKeyFactorySource,
            [NotNull] IClrAccessorSource<IClrPropertyGetter> clrPropertyGetterSource,
            [NotNull] QueryCompilationContext queryCompilationContext,
            [NotNull] QuerySourceReferenceExpression querySourceReferenceExpression,
            [NotNull] IEntityType entityType)
        {
            Check.NotNull(entityKeyFactorySource, nameof(entityKeyFactorySource));
            Check.NotNull(clrPropertyGetterSource, nameof(clrPropertyGetterSource));
            Check.NotNull(querySourceReferenceExpression, nameof(querySourceReferenceExpression));
            Check.NotNull(entityType, nameof(entityType));
            Check.NotNull(queryCompilationContext, nameof(queryCompilationContext));

            QuerySourceReferenceExpression = querySourceReferenceExpression;

            _entityType = entityType;
            _queryCompilationContext = queryCompilationContext;
            _entityKeyFactorySource = entityKeyFactorySource;
            _clrPropertyGetterSource = clrPropertyGetterSource;

            _entityKeyProperties = _entityType.GetPrimaryKey().Properties;

            _entityKeyFactory = _entityKeyFactorySource.GetKeyFactory(_entityType.GetPrimaryKey());

            _includedNavigationPaths
                = _queryCompilationContext
                    .GetTrackableIncludes(querySourceReferenceExpression.ReferencedQuerySource);

            if (_includedNavigationPaths != null)
            {
                _includedEntityTrackingInfos = new Dictionary<INavigation, IncludedEntityTrackingInfo>();

                foreach (var navigation
                    in _includedNavigationPaths.SelectMany(ns => ns))
                {
                    if (!_includedEntityTrackingInfos.ContainsKey(navigation))
                    {
                        var targetEntityType = navigation.GetTargetType();
                        var targetKey = targetEntityType.GetPrimaryKey();

                        _includedEntityTrackingInfos.Add(
                            navigation,
                            new IncludedEntityTrackingInfo(
                                targetEntityType,
                                _entityKeyFactorySource.GetKeyFactory(targetKey),
                                targetKey.Properties));
                    }
                }
            }
        }
            public DefaultExpressionTreeVisitor([NotNull] QueryCompilationContext queryCompilationContext)
            {
                Check.NotNull(queryCompilationContext, "queryCompilationContext");

                _queryCompilationContext = queryCompilationContext;
            }
 protected QueryingExpressionTreeVisitor([NotNull] QueryCompilationContext queryCompilationContext)
     : base(queryCompilationContext)
 {
 }
Ejemplo n.º 5
0
        protected virtual void OptimizeJoinClause(
            [NotNull] JoinClause joinClause,
            [NotNull] QueryModel queryModel,
            int index,
            [NotNull] Action baseVisitAction,
            [NotNull] MethodInfo operatorToFlatten,
            bool outerJoin = false)
        {
            Check.NotNull(joinClause, nameof(joinClause));
            Check.NotNull(queryModel, nameof(queryModel));
            Check.NotNull(baseVisitAction, nameof(baseVisitAction));
            Check.NotNull(operatorToFlatten, nameof(operatorToFlatten));

            RequiresClientJoin = true;

            var previousQuerySource = FindPreviousQuerySource(queryModel, index);

            var previousSelectExpression
                = previousQuerySource != null
                    ? TryGetQuery(previousQuerySource)
                    : null;

            var previousSelectProjectionCount
                = previousSelectExpression?.Projection.Count ?? -1;

            baseVisitAction();

            if (previousSelectExpression != null)
            {
                var selectExpression = TryGetQuery(joinClause);

                if (selectExpression != null)
                {
                    var sqlTranslatingExpressionVisitor
                        = _sqlTranslatingExpressionVisitorFactory.Create(this);

                    var predicate
                        = sqlTranslatingExpressionVisitor
                          .Visit(
                              Expression.Equal(
                                  joinClause.OuterKeySelector,
                                  joinClause.InnerKeySelector));

                    if (predicate != null)
                    {
                        QueriesBySource.Remove(joinClause);

                        previousSelectExpression.RemoveRangeFromProjection(previousSelectProjectionCount);

                        var tableExpression = selectExpression.Tables.Single();

                        var projection
                            = QueryCompilationContext
                              .QuerySourceRequiresMaterialization(joinClause)
                                ? selectExpression.Projection
                                : Enumerable.Empty <Expression>();

                        var joinExpression
                            = !outerJoin
                                ? previousSelectExpression.AddInnerJoin(tableExpression, projection)
                                : previousSelectExpression.AddOuterJoin(tableExpression, projection);

                        joinExpression.Predicate = predicate;

                        if (outerJoin)
                        {
                            var outerJoinOrderingExtractor = new OuterJoinOrderingExtractor();

                            outerJoinOrderingExtractor.Visit(predicate);

                            foreach (var expression in outerJoinOrderingExtractor.Expressions)
                            {
                                previousSelectExpression
                                .AddToOrderBy(new Ordering(expression, OrderingDirection.Asc));
                            }
                        }

                        Expression
                            = _queryFlattenerFactory
                              .Create(
                                  joinClause,
                                  QueryCompilationContext,
                                  operatorToFlatten,
                                  previousSelectProjectionCount)
                              .Flatten((MethodCallExpression)Expression);

                        RequiresClientJoin = false;
                    }
                }
            }

            if (RequiresClientJoin)
            {
                CheckClientEval(joinClause);
            }
        }
Ejemplo n.º 6
0
 public ProjectionExpressionTreeVisitor([NotNull] QueryCompilationContext queryCompilationContext)
     : base(queryCompilationContext)
 {
 }
 public abstract EntityQueryModelVisitor Create(
     QueryCompilationContext queryCompilationContext,
     EntityQueryModelVisitor parentEntityQueryModelVisitor);
        private Expression LiftSubQuery(
            IQuerySource querySource, Expression itemsExpression, QueryModel queryModel, Expression expression)
        {
            var subQueryExpression = itemsExpression as SubQueryExpression;

            if (subQueryExpression == null)
            {
                return(expression);
            }

            var subQueryModelVisitor
                = (RelationalQueryModelVisitor)QueryCompilationContext.CreateQueryModelVisitor(this);

            subQueryModelVisitor.VisitSubQueryModel(subQueryExpression.QueryModel);

            SelectExpression subSelectExpression = null;

            if (subQueryModelVisitor.Queries.Count == 1 &&
                !subQueryModelVisitor.RequiresClientFilter &&
                !subQueryModelVisitor.RequiresClientSelectMany &&
                !subQueryModelVisitor.RequiresClientProjection &&
                !subQueryModelVisitor.RequiresClientResultOperator)
            {
                subSelectExpression = subQueryModelVisitor.Queries.First();
            }

            if (subSelectExpression != null &&
                (!subSelectExpression.OrderBy.Any() ||
                 subSelectExpression.Limit != null) &&
                (QueryCompilationContext.IsCrossApplySupported ||
                 (!subSelectExpression.IsCorrelated() ||
                  !(querySource is AdditionalFromClause))))
            {
                subSelectExpression.PushDownSubquery().QuerySource = querySource;

                AddQuery(querySource, subSelectExpression);

                var shapedQueryMethodExpression
                    = _shapedQueryFindingExpressionVisitorFactory
                      .Create(QueryCompilationContext)
                      .Find(subQueryModelVisitor.Expression);

                var shaperLambda     = (LambdaExpression)shapedQueryMethodExpression.Arguments[3];
                var shaperMethodCall = (MethodCallExpression)shaperLambda.Body;

                var shaperMethod     = shaperMethodCall.Method;
                var shaperMethodArgs = shaperMethodCall.Arguments.ToList();

                if (!QueryCompilationContext.QuerySourceRequiresMaterialization(querySource) &&
                    shaperMethod.MethodIsClosedFormOf(RelationalEntityQueryableExpressionVisitor.CreateEntityMethodInfo))
                {
                    shaperMethod = RelationalEntityQueryableExpressionVisitor.CreateValueBufferMethodInfo;
                    shaperMethodArgs.RemoveRange(5, shaperMethodArgs.Count - 5);
                }
                else
                {
                    subSelectExpression.ExplodeStarProjection();
                }

                var innerQuerySource = (IQuerySource)((ConstantExpression)shaperMethodArgs[0]).Value;

                foreach (var queryAnnotation
                         in QueryCompilationContext.QueryAnnotations
                         .Where(qa => qa.QuerySource == innerQuerySource))
                {
                    queryAnnotation.QuerySource = querySource;
                }

                shaperMethodArgs[0] = Expression.Constant(querySource);

                var querySourceReferenceExpression
                    = queryModel.SelectClause.Selector as QuerySourceReferenceExpression;

                if (querySourceReferenceExpression != null &&
                    querySourceReferenceExpression.ReferencedQuerySource == querySource)
                {
                    var newSelectorExpression = subQueryExpression.QueryModel.SelectClause.Selector;

                    if (newSelectorExpression.Type != queryModel.SelectClause.Selector.Type)
                    {
                        newSelectorExpression
                            = Expression.Convert(
                                  subQueryExpression.QueryModel.SelectClause.Selector,
                                  queryModel.SelectClause.Selector.Type);
                    }

                    queryModel.SelectClause.Selector = newSelectorExpression;

                    QueryCompilationContext.QuerySourceMapping
                    .ReplaceMapping(
                        subQueryExpression.QueryModel.MainFromClause,
                        QueryResultScope.GetResult(
                            QueryResultScopeParameter,
                            querySource,
                            shaperMethod.ReturnType.GenericTypeArguments[0]));
                }

                return(Expression.Call(
                           QueryCompilationContext.QueryMethodProvider.ShapedQueryMethod
                           .MakeGenericMethod(shaperMethod.ReturnType),
                           shapedQueryMethodExpression.Arguments[0],
                           shapedQueryMethodExpression.Arguments[1],
                           shapedQueryMethodExpression.Arguments[2],
                           Expression.Lambda(
                               Expression.Call(shaperMethod, shaperMethodArgs),
                               shaperLambda.Parameters[0])));
            }

            return(expression);
        }
 public abstract EntityQueryModelVisitor Create(
     QueryCompilationContext queryCompilationContext,
     EntityQueryModelVisitor parentEntityQueryModelVisitor);