Ejemplo n.º 1
0
        public virtual void AddQuery([NotNull] IQuerySource querySource, [NotNull] SelectExpression selectExpression)
        {
            Check.NotNull(querySource, nameof(querySource));
            Check.NotNull(selectExpression, nameof(selectExpression));

            QueriesBySource.Add(querySource, selectExpression);
        }
Ejemplo n.º 2
0
        public virtual SelectExpression TryGetQuery([NotNull] IQuerySource querySource)
        {
            Check.NotNull(querySource, nameof(querySource));

            SelectExpression selectExpression;

            return(QueriesBySource.TryGetValue(querySource, out selectExpression)
                ? selectExpression
                : QueriesBySource.Values.SingleOrDefault(se => se.HandlesQuerySource(querySource)));
        }
        /// <summary>
        /// Get active ReadOnlyExpression
        /// </summary>
        /// <param name="querySource"></param>
        /// <returns></returns>
        public virtual ReadOnlyExpression TryGetQuery([NotNull] IQuerySource querySource)
        {
            Check.NotNull(querySource, nameof(querySource));

            return(QueriesBySource.TryGetValue(querySource, out ReadOnlyExpression roe)
                ? roe
                : QueriesBySource
                   .Values
                   .LastOrDefault(e => e.HandlesQuerySource(querySource)));
        }
        /// <summary>
        /// Add read only expression
        /// </summary>
        /// <param name="querySource"></param>
        /// <param name="readOnlyExpression"></param>
        public virtual void AddQuery(
            [NotNull] IQuerySource querySource,
            [NotNull] ReadOnlyExpression readOnlyExpression
            )
        {
            Check.NotNull(querySource, nameof(querySource));
            Check.NotNull(readOnlyExpression, nameof(readOnlyExpression));

            QueriesBySource.Add(querySource, readOnlyExpression);
        }
        public override SelectExpression TryGetQuery(IQuerySource querySource)
        {
            SelectExpression selectExpression;

            if (QueriesBySource.TryGetValue(querySource, out selectExpression))
            {
                return(selectExpression);
            }
            return(QueriesBySource.Values.SingleOrDefault(se => se.HandlesQuerySource(querySource)));
        }
        public override void VisitQueryModel(QueryModel queryModel)
        {
            base.VisitQueryModel(queryModel);

            if (ContextOptions.FindExtension <SqlServerOptionsExtension>()?.RowNumberPaging == true)
            {
                var visitor = new RowNumberPagingExpressionVisitor();

                SelectExpression mainSelectExpression;
                if (QueriesBySource.TryGetValue(queryModel.MainFromClause, out mainSelectExpression))
                {
                    visitor.Visit(mainSelectExpression);
                }

                foreach (var additionalSource in queryModel.BodyClauses.OfType <IQuerySource>())
                {
                    SelectExpression additionalFromExpression;
                    if (QueriesBySource.TryGetValue(additionalSource, out additionalFromExpression))
                    {
                        visitor.Visit(mainSelectExpression);
                    }
                }
            }
        }
Ejemplo n.º 7
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.º 8
0
        public override void VisitAdditionalFromClause(
            AdditionalFromClause fromClause, QueryModel queryModel, int index)
        {
            Check.NotNull(fromClause, nameof(fromClause));
            Check.NotNull(queryModel, nameof(queryModel));

            base.VisitAdditionalFromClause(fromClause, queryModel, index);

            RequiresClientSelectMany = true;

            var selectExpression = TryGetQuery(fromClause);

            if (selectExpression != null &&
                selectExpression.Tables.Count == 1)
            {
                var previousQuerySource = FindPreviousQuerySource(queryModel, index);

                if (previousQuerySource != null &&
                    !RequiresClientJoin)
                {
                    var previousSelectExpression = TryGetQuery(previousQuerySource);

                    if (previousSelectExpression != null)
                    {
                        if (!QueryCompilationContext.QuerySourceRequiresMaterialization(previousQuerySource))
                        {
                            previousSelectExpression.ClearProjection();
                            previousSelectExpression.IsProjectStar = false;
                        }

                        var readerOffset = previousSelectExpression.Projection.Count;

                        var correlated = selectExpression.IsCorrelated();

                        if (correlated)
                        {
                            if (!QueryCompilationContext.IsLateralJoinSupported)
                            {
                                return;
                            }

                            previousSelectExpression
                            .AddLateralJoin(selectExpression.Tables.First(), selectExpression.Projection);
                        }
                        else
                        {
                            previousSelectExpression
                            .AddCrossJoin(selectExpression.Tables.First(), selectExpression.Projection);
                        }

                        QueriesBySource.Remove(fromClause);

                        Expression
                            = _queryFlattenerFactory
                              .Create(
                                  fromClause,
                                  QueryCompilationContext,
                                  LinqOperatorProvider.SelectMany,
                                  readerOffset)
                              .Flatten((MethodCallExpression)Expression);

                        RequiresClientSelectMany = false;
                    }
                }
            }

            if (RequiresClientSelectMany)
            {
                CheckClientEval(fromClause);
            }
        }