/// <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>
        public virtual Expression HandleResultOperator(
            EntityQueryModelVisitor entityQueryModelVisitor,
            ResultOperatorBase resultOperator,
            QueryModel queryModel)
        {
            var relationalQueryModelVisitor
                = (RelationalQueryModelVisitor)entityQueryModelVisitor;

            var selectExpression
                = relationalQueryModelVisitor
                  .TryGetQuery(queryModel.MainFromClause);

            var handlerContext
                = new HandlerContext(
                      _resultOperatorHandler,
                      _model,
                      _sqlTranslatingExpressionVisitorFactory,
                      _selectExpressionFactory,
                      relationalQueryModelVisitor,
                      resultOperator,
                      queryModel,
                      selectExpression);

            Func <HandlerContext, Expression> resultHandler;

            if (relationalQueryModelVisitor.RequiresClientEval ||
                relationalQueryModelVisitor.RequiresClientSelectMany ||
                relationalQueryModelVisitor.RequiresClientJoin ||
                relationalQueryModelVisitor.RequiresClientFilter ||
                relationalQueryModelVisitor.RequiresClientOrderBy ||
                relationalQueryModelVisitor.RequiresClientResultOperator ||
                !_resultHandlers.TryGetValue(resultOperator.GetType(), out resultHandler) ||
                selectExpression == null)
            {
                return(handlerContext.EvalOnClient());
            }

            if (relationalQueryModelVisitor.RequiresClientSingleColumnResultOperator &&
                !(resultOperator is SkipResultOperator ||
                  resultOperator is TakeResultOperator ||
                  resultOperator is FirstResultOperator ||
                  resultOperator is SingleResultOperator ||
                  resultOperator is CountResultOperator ||
                  resultOperator is AllResultOperator ||
                  resultOperator is AnyResultOperator ||
                  resultOperator is GroupResultOperator))
            {
                return(handlerContext.EvalOnClient());
            }

            return(resultHandler(handlerContext));
        }
        private static Expression HandleLast(HandlerContext handlerContext)
        {
            var requiresClientResultOperator = true;

            if (handlerContext.SelectExpression.OrderBy.Any())
            {
                foreach (var ordering in handlerContext.SelectExpression.OrderBy)
                {
                    ordering.OrderingDirection
                        = ordering.OrderingDirection == OrderingDirection.Asc
                            ? OrderingDirection.Desc
                            : OrderingDirection.Asc;
                }

                handlerContext.SelectExpression.Limit = Expression.Constant(1);
                requiresClientResultOperator          = false;
            }

            requiresClientResultOperator
                = requiresClientResultOperator ||
                  (!((LastResultOperator)handlerContext.ResultOperator).ReturnDefaultWhenEmpty &&
                   handlerContext.QueryModelVisitor.ParentQueryModelVisitor != null);

            return(handlerContext.EvalOnClient(requiresClientResultOperator: requiresClientResultOperator));
        }
        private static Expression HandleDistinct(HandlerContext handlerContext)
        {
            if (!handlerContext.QueryModelVisitor.RequiresClientProjection)
            {
                var selectExpression = handlerContext.SelectExpression;

                selectExpression.IsDistinct = true;

                if (selectExpression.OrderBy.Any(o =>
                {
                    var orderByColumnExpression = o.Expression.TryGetColumnExpression();

                    if (orderByColumnExpression == null)
                    {
                        return(true);
                    }

                    return(!selectExpression.Projection.Any(e =>
                    {
                        var projectionColumnExpression = e.TryGetColumnExpression();

                        return projectionColumnExpression != null &&
                        projectionColumnExpression.Equals(orderByColumnExpression);
                    }));
                }))
                {
                    handlerContext.SelectExpression.ClearOrderBy();
                }

                return(handlerContext.EvalOnServer);
            }

            return(handlerContext.EvalOnClient());
        }
        private static Expression HandleAverage(HandlerContext handlerContext)
        {
            if (!handlerContext.QueryModelVisitor.RequiresClientProjection &&
                handlerContext.SelectExpression.Projection.Count == 1)
            {
                var expression = handlerContext.SelectExpression.Projection.First();

                if (!(expression.RemoveConvert() is SelectExpression))
                {
                    var inputType  = expression.Type;
                    var outputType = expression.Type;

                    var nonNullableInputType = inputType.UnwrapNullableType();
                    if (nonNullableInputType == typeof(int) ||
                        nonNullableInputType == typeof(long))
                    {
                        outputType = inputType.IsNullableType() ? typeof(double?) : typeof(double);
                    }

                    expression = new ExplicitCastExpression(expression, outputType);
                    var averageExpression = new SqlFunctionExpression("AVG", expression.Type, new [] { expression });

                    handlerContext.SelectExpression.SetProjectionExpression(averageExpression);

                    return((Expression)_transformClientExpressionMethodInfo
                           .MakeGenericMethod(averageExpression.Type)
                           .Invoke(null, new object [] { handlerContext }));
                }
            }

            return(handlerContext.EvalOnClient());
        }
        /// <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>
        public virtual Expression HandleResultOperator(
            EntityQueryModelVisitor entityQueryModelVisitor,
            ResultOperatorBase resultOperator,
            QueryModel queryModel)
        {
            var relationalQueryModelVisitor
                = (RelationalQueryModelVisitor)entityQueryModelVisitor;

            var selectExpression
                = relationalQueryModelVisitor
                  .TryGetQuery(queryModel.MainFromClause);

            var handlerContext
                = new HandlerContext(
                      _resultOperatorHandler,
                      _model,
                      _sqlTranslatingExpressionVisitorFactory,
                      _selectExpressionFactory,
                      relationalQueryModelVisitor,
                      resultOperator,
                      queryModel,
                      selectExpression);

            return(relationalQueryModelVisitor.RequiresClientEval ||
                   relationalQueryModelVisitor.RequiresClientSelectMany ||
                   relationalQueryModelVisitor.RequiresClientJoin ||
                   relationalQueryModelVisitor.RequiresClientFilter ||
                   relationalQueryModelVisitor.RequiresClientOrderBy ||
                   relationalQueryModelVisitor.RequiresClientResultOperator ||
                   relationalQueryModelVisitor.RequiresStreamingGroupResultOperator ||
                   !_resultHandlers.TryGetValue(resultOperator.GetType(), out var resultHandler) ||
                   selectExpression == null
                ? handlerContext.EvalOnClient()
                : resultHandler(handlerContext));
        }
示例#6
0
        private static Expression HandleAll(HandlerContext handlerContext)
        {
            var sqlTranslatingVisitor
                = handlerContext.CreateSqlTranslatingVisitor();

            PrepareSelectExpressionForAggregate(handlerContext.SelectExpression);

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

            if (predicate != null)
            {
                var innerSelectExpression = handlerContext.SelectExpression.Clone();

                innerSelectExpression.ClearProjection();
                innerSelectExpression.AddToProjection(Expression.Constant(1));
                innerSelectExpression.AddToPredicate(Expression.Not(predicate));

                if (innerSelectExpression.Limit == null &&
                    innerSelectExpression.Offset == null)
                {
                    innerSelectExpression.ClearOrderBy();
                }

                SetConditionAsProjection(
                    handlerContext,
                    Expression.Not(new ExistsExpression(innerSelectExpression)));

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

            return(handlerContext.EvalOnClient());
        }
        private static Expression HandleFirst(HandlerContext handlerContext)
        {
            handlerContext.SelectExpression.Limit = Expression.Constant(1);

            var requiresClientResultOperator = !((FirstResultOperator)handlerContext.ResultOperator).ReturnDefaultWhenEmpty &&
                                               handlerContext.QueryModelVisitor.ParentQueryModelVisitor != null;

            return(handlerContext.EvalOnClient(requiresClientResultOperator));
        }
示例#8
0
        private static Expression HandleDefaultIfEmpty(HandlerContext handlerContext)
        {
            var defaultIfEmptyResultOperator = (DefaultIfEmptyResultOperator)handlerContext.ResultOperator;

            if (defaultIfEmptyResultOperator.OptionalDefaultValue != null)
            {
                return(handlerContext.EvalOnClient());
            }

            var selectExpression = handlerContext.SelectExpression;

            selectExpression.PushDownSubquery();
            selectExpression.ExplodeStarProjection();

            var subquery = selectExpression.Tables.Single();

            selectExpression.ClearTables();

            var emptySelectExpression = handlerContext.SelectExpressionFactory.Create(handlerContext.QueryModelVisitor.QueryCompilationContext, "empty");

            emptySelectExpression.AddToProjection(new AliasExpression("empty", Expression.Constant(null)));

            selectExpression.AddTable(emptySelectExpression);

            var leftOuterJoinExpression = new LeftOuterJoinExpression(subquery);
            var constant1 = Expression.Constant(1);

            leftOuterJoinExpression.Predicate = Expression.Equal(constant1, constant1);

            selectExpression.AddTable(leftOuterJoinExpression);

            selectExpression.ProjectStarTable = subquery;

            handlerContext.QueryModelVisitor.Expression
                = new DefaultIfEmptyExpressionVisitor(
                      handlerContext.QueryModelVisitor.QueryCompilationContext)
                  .Visit(handlerContext.QueryModelVisitor.Expression);

            return(handlerContext.EvalOnClient(requiresClientResultOperator: false));
        }
        private static Expression HandleSingle(HandlerContext handlerContext)
        {
            handlerContext.SelectExpression.Limit = Expression.Constant(2);

            var returnExpression = handlerContext.EvalOnClient(requiresClientResultOperator: true);

            // For top level single, we do not require client eval
            if (handlerContext.QueryModelVisitor.ParentQueryModelVisitor == null)
            {
                handlerContext.QueryModelVisitor.RequiresClientResultOperator = false;
            }

            return(returnExpression);
        }
        private static Expression HandleSum(HandlerContext handlerContext)
        {
            if (!handlerContext.QueryModelVisitor.RequiresClientProjection)
            {
                var sumExpression
                    = new SumExpression(handlerContext.SelectExpression.Projection.Single());

                handlerContext.SelectExpression.SetProjectionExpression(sumExpression);

                return((Expression)_transformClientExpressionMethodInfo
                       .MakeGenericMethod(sumExpression.Type)
                       .Invoke(null, new object[] { handlerContext }));
            }

            return(handlerContext.EvalOnClient());
        }
        private static Expression HandleAll(HandlerContext handlerContext)
        {
            var sqlTranslatingVisitor
                = handlerContext.CreateSqlTranslatingVisitor(bindParentQueries: true);

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

            if (predicate != null)
            {
                var innerSelectExpression = handlerContext.SelectExpression.Clone();

                innerSelectExpression.ClearProjection();
                innerSelectExpression.AddToProjection(Expression.Constant(1));

                if (handlerContext.SelectExpression.Predicate != null)
                {
                    innerSelectExpression.Predicate
                        = Expression.AndAlso(
                              handlerContext.SelectExpression.Predicate,
                              Expression.Not(predicate));
                }
                else
                {
                    innerSelectExpression.Predicate = Expression.Not(predicate);
                }

                if (innerSelectExpression.Limit == null &&
                    innerSelectExpression.Offset == null)
                {
                    innerSelectExpression.ClearOrderBy();
                }

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

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

            return(handlerContext.EvalOnClient());
        }
示例#12
0
        private static Expression HandleAverage(HandlerContext handlerContext)
        {
            if (!handlerContext.QueryModelVisitor.RequiresClientProjection &&
                handlerContext.SelectExpression.Projection.Count == 1)
            {
                PrepareSelectExpressionForAggregate(handlerContext.SelectExpression);

                var expression = handlerContext.SelectExpression.Projection.First();

                if (!(expression.RemoveConvert() is SelectExpression))
                {
                    var inputType  = handlerContext.QueryModel.SelectClause.Selector.Type;
                    var outputType = inputType;

                    var nonNullableInputType = inputType.UnwrapNullableType();
                    if (nonNullableInputType == typeof(int) ||
                        nonNullableInputType == typeof(long))
                    {
                        outputType = inputType.IsNullableType() ? typeof(double?) : typeof(double);
                    }

                    expression = (expression as ExplicitCastExpression)?.Operand ?? expression;
                    expression = UnwrapAliasExpression(expression);
                    expression = new ExplicitCastExpression(expression, outputType);
                    Expression averageExpression = new SqlFunctionExpression(
                        "AVG",
                        outputType,
                        new[] { expression });

                    if (nonNullableInputType == typeof(float))
                    {
                        averageExpression = new ExplicitCastExpression(averageExpression, inputType);
                    }

                    handlerContext.SelectExpression.SetProjectionExpression(averageExpression);

                    var averageExpressionType = averageExpression.Type;
                    var throwOnNullResult     = DetermineAggregateThrowingBehavior(handlerContext, averageExpressionType);

                    return((Expression)_transformClientExpressionMethodInfo
                           .MakeGenericMethod(averageExpressionType)
                           .Invoke(null, new object[] { handlerContext, throwOnNullResult }));
                }
            }

            return(handlerContext.EvalOnClient());
        }
        private static Expression HandleTake(HandlerContext handlerContext)
        {
            var takeResultOperator = (TakeResultOperator)handlerContext.ResultOperator;

            var sqlTranslatingExpressionVisitor = handlerContext.CreateSqlTranslatingVisitor(bindParentQueries: true);

            var limit = sqlTranslatingExpressionVisitor.Visit(takeResultOperator.Count);

            if (limit != null)
            {
                handlerContext.SelectExpression.Limit = takeResultOperator.Count;

                return(handlerContext.EvalOnServer);
            }

            return(handlerContext.EvalOnClient());
        }
        private static Expression HandleLast(HandlerContext handlerContext)
        {
            if (handlerContext.SelectExpression.OrderBy.Any())
            {
                foreach (var ordering in handlerContext.SelectExpression.OrderBy)
                {
                    ordering.OrderingDirection
                        = ordering.OrderingDirection == OrderingDirection.Asc
                            ? OrderingDirection.Desc
                            : OrderingDirection.Asc;
                }

                handlerContext.SelectExpression.Limit = Expression.Constant(1);
            }

            return(handlerContext.EvalOnClient(requiresClientResultOperator: false));
        }
        private static Expression HandleSkip(HandlerContext handlerContext)
        {
            var skipResultOperator = (SkipResultOperator)handlerContext.ResultOperator;

            var sqlTranslatingExpressionVisitor = handlerContext.CreateSqlTranslatingVisitor(bindParentQueries: true);

            var offset = sqlTranslatingExpressionVisitor.Visit(skipResultOperator.Count);

            if (offset != null)
            {
                handlerContext.SelectExpression.Offset = offset;

                return(handlerContext.EvalOnServer);
            }

            return(handlerContext.EvalOnClient());
        }
        private static Expression HandleGroup(HandlerContext handlerContext)
        {
            var sqlTranslatingExpressionVisitor
                = handlerContext.SqlTranslatingExpressionVisitorFactory
                  .Create(
                      handlerContext.QueryModelVisitor,
                      handlerContext.SelectExpression);

            var groupResultOperator = (GroupResultOperator)handlerContext.ResultOperator;

            var sqlExpression
                = sqlTranslatingExpressionVisitor.Visit(groupResultOperator.KeySelector);

            if (sqlExpression != null)
            {
                handlerContext.SelectExpression.ClearOrderBy();

                var columns = (sqlExpression as ConstantExpression)?.Value as Expression[];

                if (columns != null)
                {
                    foreach (var column in columns)
                    {
                        handlerContext.SelectExpression
                        .AddToOrderBy(new Ordering(column, OrderingDirection.Asc));
                    }
                }
                else
                {
                    handlerContext.SelectExpression
                    .AddToOrderBy(new Ordering(sqlExpression, OrderingDirection.Asc));
                }
            }

            var oldGroupByCall = (MethodCallExpression)handlerContext.EvalOnClient();

            return(Expression.Call(
                       handlerContext.QueryModelVisitor.QueryCompilationContext.QueryMethodProvider.GroupByMethod
                       .MakeGenericMethod(oldGroupByCall.Method.GetGenericArguments()),
                       oldGroupByCall.Arguments));
        }
示例#17
0
        private static Expression HandleAll(HandlerContext handlerContext)
        {
            var filteringVisitor
                = handlerContext.SqlTranslatingExpressionVisitorFactory
                  .Create(
                      handlerContext.QueryModelVisitor,
                      handlerContext.SelectExpression);

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

            if (predicate != null)
            {
                var innerSelectExpression
                    = handlerContext.SelectExpressionFactory.Create(handlerContext.QueryModelVisitor.QueryCompilationContext);

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

                if (handlerContext.SelectExpression.Predicate != null)
                {
                    innerSelectExpression.Predicate
                        = Expression.AndAlso(
                              handlerContext.SelectExpression.Predicate,
                              innerSelectExpression.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());
        }
        private static Expression HandleSum(HandlerContext handlerContext)
        {
            if (!handlerContext.QueryModelVisitor.RequiresClientProjection &&
                handlerContext.SelectExpression.Projection.Count == 1)
            {
                var expression = handlerContext.SelectExpression.Projection.First();

                if (!(expression.RemoveConvert() is SelectExpression))
                {
                    var sumExpression = new SqlFunctionExpression("SUM", expression.Type, new [] { expression });

                    handlerContext.SelectExpression.SetProjectionExpression(sumExpression);

                    return((Expression)_transformClientExpressionMethodInfo
                           .MakeGenericMethod(sumExpression.Type)
                           .Invoke(null, new object [] { handlerContext }));
                }
            }

            return(handlerContext.EvalOnClient());
        }
示例#19
0
        public virtual Expression HandleResultOperator(
            EntityQueryModelVisitor entityQueryModelVisitor,
            ResultOperatorBase resultOperator,
            QueryModel queryModel)
        {
            var relationalQueryModelVisitor
                = (RelationalQueryModelVisitor)entityQueryModelVisitor;

            var selectExpression
                = relationalQueryModelVisitor
                  .TryGetQuery(queryModel.MainFromClause);

            var handlerContext
                = new HandlerContext(
                      _resultOperatorHandler,
                      _model,
                      _relationalAnnotationProvider,
                      _sqlTranslatingExpressionVisitorFactory,
                      _selectExpressionFactory,
                      relationalQueryModelVisitor,
                      resultOperator,
                      queryModel,
                      selectExpression);

            Func <HandlerContext, Expression> resultHandler;

            if (relationalQueryModelVisitor.RequiresClientFilter ||
                relationalQueryModelVisitor.RequiresClientResultOperator ||
                relationalQueryModelVisitor.RequiresClientSelectMany ||
                !_resultHandlers.TryGetValue(resultOperator.GetType(), out resultHandler) ||
                selectExpression == null)
            {
                return(handlerContext.EvalOnClient());
            }

            return(resultHandler(handlerContext));
        }
示例#20
0
        private static Expression HandleContains(HandlerContext handlerContext)
        {
            var filteringVisitor = handlerContext.CreateSqlTranslatingVisitor();

            var itemResultOperator = (ContainsResultOperator)handlerContext.ResultOperator;

            var item = filteringVisitor.Visit(itemResultOperator.Item);

            if (item != null)
            {
                if (item is SelectExpression itemSelectExpression)
                {
                    var queryCompilationContext = handlerContext.QueryModelVisitor.QueryCompilationContext;
                    var entityType = queryCompilationContext.FindEntityType(handlerContext.QueryModel.MainFromClause)
                                     ?? handlerContext.Model.FindEntityType(handlerContext.QueryModel.MainFromClause.ItemType);

                    if (entityType != null)
                    {
                        var outerSelectExpression = handlerContext.SelectExpressionFactory.Create(queryCompilationContext);

                        var collectionSelectExpression
                            = handlerContext.SelectExpression.Clone(queryCompilationContext.CreateUniqueTableAlias());
                        outerSelectExpression.AddTable(collectionSelectExpression);

                        itemSelectExpression.Alias = queryCompilationContext.CreateUniqueTableAlias();
                        var joinExpression = outerSelectExpression.AddInnerJoin(itemSelectExpression);

                        foreach (var property in entityType.FindPrimaryKey().Properties)
                        {
                            var itemProperty = itemSelectExpression.BindProperty(
                                property,
                                itemSelectExpression.ProjectStarTable.QuerySource);

                            itemSelectExpression.AddToProjection(itemProperty);

                            var collectionProperty = collectionSelectExpression.BindProperty(
                                property,
                                collectionSelectExpression.ProjectStarTable.QuerySource);

                            collectionSelectExpression.AddToProjection(collectionProperty);

                            var predicate = Expression.Equal(
                                collectionProperty.LiftExpressionFromSubquery(collectionSelectExpression),
                                itemProperty.LiftExpressionFromSubquery(itemSelectExpression));

                            joinExpression.Predicate
                                = joinExpression.Predicate == null
                                    ? predicate
                                    : Expression.AndAlso(
                                      joinExpression.Predicate,
                                      predicate);
                        }

                        SetConditionAsProjection(
                            handlerContext,
                            new ExistsExpression(outerSelectExpression));

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

                SetConditionAsProjection(
                    handlerContext,
                    new InExpression(
                        item,
                        handlerContext.SelectExpression.Clone("")));

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

            return(handlerContext.EvalOnClient());
        }
        private static Expression HandleContains(HandlerContext handlerContext)
        {
            var filteringVisitor = handlerContext.CreateSqlTranslatingVisitor(bindParentQueries: true);

            var itemResultOperator = (ContainsResultOperator)handlerContext.ResultOperator;

            var item = filteringVisitor.Visit(itemResultOperator.Item);

            if (item != null)
            {
                var itemSelectExpression = item as SelectExpression;

                if (itemSelectExpression != null)
                {
                    var entityType = handlerContext.Model.FindEntityType(handlerContext.QueryModel.MainFromClause.ItemType);

                    if (entityType != null)
                    {
                        var outterSelectExpression = handlerContext.SelectExpressionFactory.Create(handlerContext.QueryModelVisitor.QueryCompilationContext);
                        outterSelectExpression.SetProjectionExpression(Expression.Constant(1));

                        var collectionSelectExpression
                            = handlerContext.SelectExpression.Clone(handlerContext.QueryModelVisitor.QueryCompilationContext.CreateUniqueTableAlias());
                        outterSelectExpression.AddTable(collectionSelectExpression);

                        itemSelectExpression.Alias = handlerContext.QueryModelVisitor.QueryCompilationContext.CreateUniqueTableAlias();
                        var joinExpression = outterSelectExpression.AddInnerJoin(itemSelectExpression);

                        foreach (var property in entityType.FindPrimaryKey().Properties)
                        {
                            itemSelectExpression.AddToProjection(
                                new ColumnExpression(
                                    property.Name,
                                    property,
                                    itemSelectExpression.Tables.First()));

                            collectionSelectExpression.AddToProjection(
                                new ColumnExpression(
                                    property.Name,
                                    property,
                                    collectionSelectExpression.Tables.First()));

                            var predicate = Expression.Equal(
                                new ColumnExpression(
                                    property.Name,
                                    property,
                                    collectionSelectExpression),
                                new ColumnExpression(
                                    property.Name,
                                    property,
                                    itemSelectExpression));

                            joinExpression.Predicate
                                = joinExpression.Predicate == null
                                    ? predicate
                                    : Expression.AndAlso(
                                      joinExpression.Predicate,
                                      predicate);
                        }

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

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

                SetProjectionConditionalExpression(
                    handlerContext,
                    Expression.Condition(
                        new InExpression(
                            new AliasExpression(item),
                            handlerContext.SelectExpression.Clone("")),
                        Expression.Constant(true),
                        Expression.Constant(false),
                        typeof(bool)));

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

            return(handlerContext.EvalOnClient());
        }
示例#22
0
 private static Expression HandleCast(HandlerContext handlerContext)
 => handlerContext.EvalOnClient(requiresClientResultOperator: false);
示例#23
0
        private static Expression HandleOfType(HandlerContext handlerContext)
        {
            var ofTypeResultOperator
                = (OfTypeResultOperator)handlerContext.ResultOperator;

            var entityType = handlerContext.Model.FindEntityType(ofTypeResultOperator.SearchedItemType);

            if (entityType == null)
            {
                return(handlerContext.EvalOnClient());
            }

            var concreteEntityTypes
                = entityType.GetConcreteTypesInHierarchy().ToArray();

            if (concreteEntityTypes.Length != 1 ||
                concreteEntityTypes[0].RootType() != concreteEntityTypes[0])
            {
                var relationalMetadataExtensionProvider
                    = handlerContext.RelationalAnnotationProvider;

                var discriminatorProperty
                    = relationalMetadataExtensionProvider.For(concreteEntityTypes[0]).DiscriminatorProperty;

                var projectionIndex
                    = handlerContext.SelectExpression
                      .GetProjectionIndex(discriminatorProperty, handlerContext.QueryModel.MainFromClause);

                if (projectionIndex < 0)
                {
                    projectionIndex
                        = handlerContext.SelectExpression
                          .AddToProjection(
                              relationalMetadataExtensionProvider.For(discriminatorProperty).ColumnName,
                              discriminatorProperty,
                              handlerContext.QueryModel.MainFromClause);
                }

                var discriminatorColumn
                    = handlerContext.SelectExpression.Projection[projectionIndex];

                var discriminatorPredicate
                    = concreteEntityTypes
                      .Select(concreteEntityType =>
                              Expression.Equal(
                                  discriminatorColumn,
                                  Expression.Constant(relationalMetadataExtensionProvider.For(concreteEntityType).DiscriminatorValue)))
                      .Aggregate((current, next) => Expression.OrElse(next, current));

                handlerContext.SelectExpression.Predicate
                    = new DiscriminatorReplacingExpressionVisitor(
                          discriminatorPredicate,
                          handlerContext.QueryModel.MainFromClause)
                      .Visit(handlerContext.SelectExpression.Predicate);
            }

            return(Expression.Call(
                       handlerContext.QueryModelVisitor.QueryCompilationContext.LinqOperatorProvider.Cast
                       .MakeGenericMethod(ofTypeResultOperator.SearchedItemType),
                       handlerContext.QueryModelVisitor.Expression));
        }
        private static Expression HandleFirst(HandlerContext handlerContext)
        {
            handlerContext.SelectExpression.Limit = Expression.Constant(1);

            return(handlerContext.EvalOnClient(requiresClientResultOperator: false));
        }
        private static Expression HandleOfType(HandlerContext handlerContext)
        {
            var ofTypeResultOperator
                = (OfTypeResultOperator)handlerContext.ResultOperator;

            var entityType = handlerContext.Model.FindEntityType(ofTypeResultOperator.SearchedItemType);

            if (entityType == null)
            {
                return(handlerContext.EvalOnClient());
            }

            var concreteEntityTypes
                = entityType.GetConcreteTypesInHierarchy().ToArray();

            if (concreteEntityTypes.Length != 1 ||
                concreteEntityTypes[0].RootType() != concreteEntityTypes[0])
            {
                var relationalMetadataExtensionProvider
                    = handlerContext.RelationalAnnotationProvider;

                var discriminatorProperty
                    = relationalMetadataExtensionProvider.For(concreteEntityTypes[0]).DiscriminatorProperty;

                var projectionIndex
                    = handlerContext.SelectExpression
                      .GetProjectionIndex(discriminatorProperty, handlerContext.QueryModel.MainFromClause);

                if (projectionIndex < 0)
                {
                    projectionIndex
                        = handlerContext.SelectExpression
                          .AddToProjection(
                              relationalMetadataExtensionProvider.For(discriminatorProperty).ColumnName,
                              discriminatorProperty,
                              handlerContext.QueryModel.MainFromClause);
                }

                var discriminatorColumn
                    = handlerContext.SelectExpression.Projection[projectionIndex];

                var discriminatorPredicate
                    = concreteEntityTypes
                      .Select(concreteEntityType =>
                              Expression.Equal(
                                  discriminatorColumn,
                                  Expression.Constant(relationalMetadataExtensionProvider.For(concreteEntityType).DiscriminatorValue)))
                      .Aggregate((current, next) => Expression.OrElse(next, current));

                handlerContext.SelectExpression.Predicate
                    = new DiscriminatorReplacingExpressionVisitor(
                          discriminatorPredicate,
                          handlerContext.QueryModel.MainFromClause)
                      .Visit(handlerContext.SelectExpression.Predicate);
            }

            var shapedQueryMethod = (MethodCallExpression)handlerContext.QueryModelVisitor.Expression;
            var entityShaper      = (EntityShaper)((ConstantExpression)shapedQueryMethod.Arguments[2]).Value;

            return(Expression.Call(
                       shapedQueryMethod.Method
                       .GetGenericMethodDefinition()
                       .MakeGenericMethod(ofTypeResultOperator.SearchedItemType),
                       shapedQueryMethod.Arguments[0],
                       shapedQueryMethod.Arguments[1],
                       Expression.Constant(
                           _createDowncastingShaperMethodInfo
                           .MakeGenericMethod(ofTypeResultOperator.SearchedItemType)
                           .Invoke(null, new object[] { entityShaper }))));
        }
        private static Expression HandleSingle(HandlerContext handlerContext)
        {
            handlerContext.SelectExpression.Limit = Expression.Constant(2);

            return(handlerContext.EvalOnClient(requiresClientResultOperator: true));
        }