Пример #1
0
        private static Expression HandleAll(HandlerContext handlerContext)
        {
            var filteringVisitor
                = new SqlTranslatingExpressionVisitor(
                      handlerContext.QueryModelVisitor,
                      handlerContext.SelectExpression);

            var predicate
                = filteringVisitor.Visit(
                      ((AllResultOperator)handlerContext.ResultOperator).Predicate);

            if (predicate != null)
            {
                var innerSelectExpression = new SelectExpression();

                innerSelectExpression.AddTables(handlerContext.SelectExpression.Tables);
                innerSelectExpression.Predicate = Expression.Not(predicate);

                SetProjectionConditionalExpression(
                    handlerContext,
                    Expression.Condition(
                        Expression.Not(new ExistsExpression(innerSelectExpression)),
                        Expression.Constant(true),
                        Expression.Constant(false),
                        typeof(bool)));

                return(TransformClientExpression <bool>(handlerContext));
            }

            return(handlerContext.EvalOnClient);
        }
        public override void VisitWhereClause(WhereClause whereClause, QueryModel queryModel, int index)
        {
            if (Expression is QueryShaperExpression queryShaperExpression)
            {
                if (queryShaperExpression.QueryExpression is DocumentQueryExpression documentQueryExpression)
                {
                    var selectExpression = documentQueryExpression.SelectExpression;
                    var sqlTranslatingExpressionVisitor = new SqlTranslatingExpressionVisitor(
                        selectExpression, QueryCompilationContext);
                    var sqlPredicate = sqlTranslatingExpressionVisitor.Visit(whereClause.Predicate);

                    if (sqlTranslatingExpressionVisitor.Translated)
                    {
                        selectExpression.AddToPredicate(sqlPredicate);

                        return;
                    }
                }

                if (AllMembersBoundToJObject)
                {
                    var fromClause            = queryModel.MainFromClause;
                    var previousParameterType = CurrentParameter.Type;

                    // Temporarily change current parameter to JObject to try binding to it without materializing the entity
                    UpdateCurrentParameter(fromClause, typeof(JObject));

                    var predicate = ReplaceClauseReferences(whereClause.Predicate);

                    if (AllMembersBoundToJObject)
                    {
                        Expression = new QueryShaperExpression(
                            QueryCompilationContext.IsAsyncQuery,
                            Expression.Call(
                                LinqOperatorProvider.Where.MakeGenericMethod(CurrentParameter.Type),
                                queryShaperExpression.QueryExpression,
                                Expression.Lambda(predicate, CurrentParameter)),
                            queryShaperExpression.Shaper);

                        if (CurrentParameter.Type == typeof(JObject))
                        {
                            UpdateCurrentParameter(fromClause, previousParameterType);
                        }

                        return;
                    }

                    UpdateCurrentParameter(fromClause, previousParameterType);
                }
            }

            base.VisitWhereClause(whereClause, queryModel, index);
        }
Пример #3
0
        public override void VisitOrderByClause(OrderByClause orderByClause, QueryModel queryModel, int index)
        {
            Check.NotNull(orderByClause, nameof(orderByClause));
            Check.NotNull(queryModel, nameof(queryModel));

            var selectExpression      = TryGetQuery(queryModel.MainFromClause);
            var requiresClientOrderBy = selectExpression == null;

            if (!requiresClientOrderBy)
            {
                var sqlTranslatingExpressionVisitor
                    = new SqlTranslatingExpressionVisitor(
                          this, selectExpression, bindParentQueries: _bindParentQueries);

                var orderings = new List <Ordering>();

                foreach (var ordering in orderByClause.Orderings)
                {
                    var sqlOrderingExpression
                        = sqlTranslatingExpressionVisitor
                          .Visit(ordering.Expression);

                    if (sqlOrderingExpression == null)
                    {
                        break;
                    }

                    orderings.Add(
                        new Ordering(
                            sqlOrderingExpression,
                            ordering.OrderingDirection));
                }

                if (orderings.Count == orderByClause.Orderings.Count)
                {
                    selectExpression.PrependToOrderBy(orderings);
                }
                else
                {
                    requiresClientOrderBy = true;
                }
            }

            if (RequiresClientEval || requiresClientOrderBy)
            {
                base.VisitOrderByClause(orderByClause, queryModel, index);
            }
        }
Пример #4
0
        public override void VisitWhereClause(WhereClause whereClause, QueryModel queryModel, int index)
        {
            Check.NotNull(whereClause, nameof(whereClause));
            Check.NotNull(queryModel, nameof(queryModel));

            var selectExpression     = TryGetQuery(queryModel.MainFromClause);
            var requiresClientFilter = selectExpression == null;

            if (!requiresClientFilter)
            {
                var sqlTranslatingExpressionVisitor
                    = new SqlTranslatingExpressionVisitor(
                          this, selectExpression, whereClause.Predicate, _bindParentQueries);

                var sqlPredicateExpression = sqlTranslatingExpressionVisitor.Visit(whereClause.Predicate);

                if (sqlPredicateExpression != null)
                {
                    selectExpression.Predicate
                        = selectExpression.Predicate == null
                            ? sqlPredicateExpression
                            : Expression.AndAlso(selectExpression.Predicate, sqlPredicateExpression);
                }
                else
                {
                    requiresClientFilter = true;
                }

                if (sqlTranslatingExpressionVisitor.ClientEvalPredicate != null &&
                    selectExpression.Predicate != null)
                {
                    requiresClientFilter = true;
                    whereClause          = new WhereClause(sqlTranslatingExpressionVisitor.ClientEvalPredicate);
                }
            }

            _requiresClientFilter |= requiresClientFilter;

            if (RequiresClientFilter)
            {
                base.VisitWhereClause(whereClause, queryModel, index);
            }
        }
Пример #5
0
        public override void VisitWhereClause(WhereClause whereClause, QueryModel queryModel, int index)
        {
            if (Expression is QueryShaperExpression queryShaperExpression &&
                queryShaperExpression.QueryExpression is DocumentQueryExpression documentQueryExpression)
            {
                var selectExpression = documentQueryExpression.SelectExpression;
                var sqlTranslatingExpressionVisitor = new SqlTranslatingExpressionVisitor(
                    selectExpression, QueryCompilationContext);
                var sqlPredicate = sqlTranslatingExpressionVisitor.Visit(whereClause.Predicate);

                if (sqlPredicate != null)
                {
                    selectExpression.AddToPredicate(sqlPredicate);

                    return;
                }
            }

            base.VisitWhereClause(whereClause, queryModel, index);
        }
        public override void VisitWhereClause(WhereClause whereClause, QueryModel queryModel, int index)
        {
            Debug.Assert(Expression is QueryShaperExpression, "Invalid Expression encountered");

            var queryShaperExpression = (QueryShaperExpression)Expression;

            if (queryShaperExpression.QueryExpression is DocumentQueryExpression documentQueryExpression)
            {
                var selectExpression = documentQueryExpression.SelectExpression;
                var sqlTranslatingExpressionVisitor = new SqlTranslatingExpressionVisitor(
                    selectExpression, QueryCompilationContext);
                var sqlPredicate = sqlTranslatingExpressionVisitor.Visit(whereClause.Predicate);

                if (sqlPredicate != null)
                {
                    selectExpression.AddToPredicate(sqlPredicate);

                    return;
                }
            }

            var fromClause = queryModel.MainFromClause;

            // Change current parameter to JObject
            UpdateCurrentParameter(fromClause, typeof(JObject));

            var predicate = ReplaceClauseReferences(whereClause.Predicate);

            Expression = new QueryShaperExpression(
                Expression.Call(LinqOperatorProvider.Where.MakeGenericMethod(CurrentParameter.Type),
                                queryShaperExpression.QueryExpression,
                                Expression.Lambda(predicate, CurrentParameter)),
                queryShaperExpression.Shaper);

            UpdateCurrentParameter(fromClause, Expression.Type.TryGetSequenceType());

            //base.VisitWhereClause(whereClause, queryModel, index);
        }
        public override Expression Visit(Expression expression)
        {
            var selectExpression = QueryModelVisitor.TryGetQuery(_querySource);

            if (expression != null
                && !(expression is ConstantExpression)
                && selectExpression != null)
            {
                var sqlExpression
                    = new SqlTranslatingExpressionVisitor(
                        _queryModelVisitor, selectExpression, inProjection: true)
                        .Visit(expression);

                if (sqlExpression == null)
                {
                    if (!(expression is QuerySourceReferenceExpression))
                    {
                        _queryModelVisitor.RequiresClientProjection = true;
                    }
                }
                else
                {
                    if (!(expression is NewExpression))
                    {
                        AliasExpression aliasExpression;

                        int index;

                        if (!(expression is QuerySourceReferenceExpression))
                        {
                            var columnExpression = sqlExpression.TryGetColumnExpression();

                            if (columnExpression != null)
                            {
                                index = selectExpression.AddToProjection(sqlExpression);

                                aliasExpression = selectExpression.Projection[index] as AliasExpression;

                                if (aliasExpression != null)
                                {
                                    aliasExpression.SourceExpression = expression;
                                }

                                return expression;
                            }
                        }

                        if (!(sqlExpression is ConstantExpression))
                        {
                            index = selectExpression.AddToProjection(sqlExpression);

                            aliasExpression = selectExpression.Projection[index] as AliasExpression;

                            if (aliasExpression != null)
                            {
                                aliasExpression.SourceExpression = expression;
                            }

                            return
                                QueryModelVisitor.BindReadValueMethod(
                                    expression.Type,
                                    QueryResultScope.GetResult(
                                        EntityQueryModelVisitor.QueryResultScopeParameter,
                                        _querySource,
                                        typeof(ValueBuffer)),
                                    index);
                        }
                    }
                }
            }

            return base.Visit(expression);
        }
Пример #8
0
        public override void VisitJoinClause(JoinClause joinClause, QueryModel queryModel, int index)
        {
            Check.NotNull(joinClause, nameof(joinClause));
            Check.NotNull(queryModel, nameof(queryModel));

            var previousQuerySource = FindPreviousQuerySource(queryModel, index);

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

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

            base.VisitJoinClause(joinClause, queryModel, index);

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

                if (selectExpression != null)
                {
                    var filteringExpressionVisitor
                        = new SqlTranslatingExpressionVisitor(this, targetSelectExpression: null);

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

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

                        previousSelectExpression.RemoveRangeFromProjection(previousSelectProjectionCount);

                        var innerJoinExpression
                            = previousSelectExpression
                              .AddInnerJoin(
                                  selectExpression.Tables.Single(),
                                  QueryCompilationContext
                                  .QuerySourceRequiresMaterialization(joinClause)
                                        ? selectExpression.Projection
                                        : Enumerable.Empty <Expression>());

                        innerJoinExpression.Predicate = predicate;

                        Expression
                            = new QueryFlatteningExpressionVisitor(
                                  previousQuerySource,
                                  joinClause,
                                  QueryCompilationContext,
                                  previousSelectProjectionCount,
                                  LinqOperatorProvider.Join)
                              .Visit(Expression);
                    }
                    else
                    {
                        previousSelectExpression.RemoveRangeFromProjection(previousSelectProjectionCount);
                    }
                }
            }
        }
Пример #9
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));

            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 = new SqlTranslatingExpressionVisitor(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;

                        Expression
                            = new QueryFlatteningExpressionVisitor(
                                  previousQuerySource,
                                  joinClause,
                                  QueryCompilationContext,
                                  previousSelectProjectionCount,
                                  operatorToFlatten)
                              .Visit(Expression);
                    }
                    else
                    {
                        previousSelectExpression
                        .RemoveRangeFromProjection(previousSelectProjectionCount);
                    }
                }
            }
        }