private static Expression HandleAll(HandlerContext handlerContext)
        {
            var filteringVisitor
                = new SqlTranslatingExpressionTreeVisitor(handlerContext.QueryModelVisitor);

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

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

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

                SetProjectionCaseExpression(
                    handlerContext,
                    new CaseExpression(Expression.Not(new ExistsExpression(innerSelectExpression))));

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

            return(handlerContext.EvalOnClient);
        }
Пример #2
0
        public override void VisitOrderByClause(OrderByClause orderByClause, QueryModel queryModel, int index)
        {
            var selectExpression      = TryGetQuery(queryModel.MainFromClause);
            var requiresClientOrderBy = selectExpression == null;

            if (!requiresClientOrderBy)
            {
                var sqlTranslatingExpressionTreeVisitor
                    = new SqlTranslatingExpressionTreeVisitor(this);

                var orderings = new List <Ordering>();

                foreach (var ordering in orderByClause.Orderings)
                {
                    var sqlOrderingExpression
                        = sqlTranslatingExpressionTreeVisitor
                          .VisitExpression(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);
            }
        }
        public override void VisitWhereClause(WhereClause whereClause, QueryModel queryModel, int index)
        {
            var selectExpression   = TryGetQuery(queryModel.MainFromClause);
            var requiresClientEval = selectExpression == null;

            if (!requiresClientEval)
            {
                var translatingVisitor     = new SqlTranslatingExpressionTreeVisitor(this, whereClause.Predicate);
                var sqlPredicateExpression = translatingVisitor.VisitExpression(whereClause.Predicate);

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

                if (translatingVisitor.ClientEvalPredicate != null)
                {
                    requiresClientEval = true;
                    whereClause        = new WhereClause(translatingVisitor.ClientEvalPredicate);
                }
            }

            if (requiresClientEval)
            {
                base.VisitWhereClause(whereClause, queryModel, index);
            }

            _requiresClientFilter |= requiresClientEval;
        }
        public override void VisitJoinClause(JoinClause joinClause, QueryModel queryModel, int index)
        {
            var previousQuerySource
                = index == 0
                    ? queryModel.MainFromClause
                    : queryModel.BodyClauses[index - 1] as IQuerySource;

            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 filteringExpressionTreeVisitor
                        = new SqlTranslatingExpressionTreeVisitor(this);

                    var predicate
                        = filteringExpressionTreeVisitor
                          .VisitExpression(
                              Expression.Equal(
                                  joinClause.OuterKeySelector,
                                  joinClause.InnerKeySelector));

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

                        previousSelectExpression.RemoveRangeFromProjection(previousSelectProjectionCount);

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

                        innerJoinExpression.Predicate = predicate;

                        Expression
                            = new QueryFlatteningExpressionTreeVisitor(
                                  previousQuerySource,
                                  joinClause,
                                  QueryCompilationContext,
                                  previousSelectProjectionCount,
                                  LinqOperatorProvider.Join)
                              .VisitExpression(Expression);
                    }
                    else
                    {
                        previousSelectExpression.RemoveRangeFromProjection(previousSelectProjectionCount);
                    }
                }
            }
        }