public void Process(NonAggregatingGroupBy resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
        {
            var selector        = queryModelVisitor.Model.SelectClause.Selector;
            var keySelector     = resultOperator.GroupBy.KeySelector;
            var elementSelector = resultOperator.GroupBy.ElementSelector;

            var sourceType  = selector.Type;
            var keyType     = keySelector.Type;
            var elementType = elementSelector.Type;

            // Stuff in the group by that doesn't map to HQL.  Run it client-side
            var listParameter = Expression.Parameter(typeof(IEnumerable <object>), "list");

            var keySelectorExpr = ReverseResolvingExpressionVisitor.ReverseResolve(selector, keySelector);

            var elementSelectorExpr = ReverseResolvingExpressionVisitor.ReverseResolve(selector, elementSelector);

            var groupByMethod = ReflectionCache.EnumerableMethods.GroupByWithElementSelectorDefinition
                                .MakeGenericMethod(new[] { sourceType, keyType, elementType });

            var castToItem = ReflectionCache.EnumerableMethods.CastDefinition.MakeGenericMethod(new[] { sourceType });

            var toList = ReflectionCache.EnumerableMethods.ToListDefinition.MakeGenericMethod(new[] { resultOperator.GroupBy.ItemType });

            Expression castToItemExpr = Expression.Call(castToItem, listParameter);

            var groupByExpr = Expression.Call(groupByMethod, castToItemExpr, keySelectorExpr, elementSelectorExpr);

            var toListExpr = Expression.Call(toList, groupByExpr);

            var lambdaExpr = Expression.Lambda(toListExpr, listParameter);

            tree.AddListTransformer(lambdaExpr);
        }
        public void Process(AggregateResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
        {
            var inputExpr       = ((StreamedSequenceInfo)queryModelVisitor.PreviousEvaluationType).ItemExpression;
            var inputType       = inputExpr.Type;
            var paramExpr       = Expression.Parameter(inputType, "item");
            var accumulatorFunc = Expression.Lambda(
                ReplacingExpressionTreeVisitor.Replace(inputExpr, paramExpr, resultOperator.Func.Body),
                resultOperator.Func.Parameters[0],
                paramExpr);

            var inputList = Expression.Parameter(typeof(IEnumerable <>).MakeGenericType(typeof(object)), "inputList");

            var castToItem     = ReflectionCache.EnumerableMethods.CastDefinition.MakeGenericMethod(new[] { inputType });
            var castToItemExpr = Expression.Call(castToItem, inputList);

            var aggregate = ReflectionCache.EnumerableMethods.AggregateDefinition.MakeGenericMethod(inputType);

            MethodCallExpression call = Expression.Call(
                aggregate,
                castToItemExpr,
                accumulatorFunc
                );

            tree.AddListTransformer(Expression.Lambda(call, inputList));
        }
Пример #3
0
        public void Process(NonAggregatingGroupBy resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
        {
            var tSource  = queryModelVisitor.Model.SelectClause.Selector.Type;
            var tKey     = resultOperator.GroupBy.KeySelector.Type;
            var tElement = resultOperator.GroupBy.ElementSelector.Type;

            // Stuff in the group by that doesn't map to HQL.  Run it client-side
            var listParameter = Expression.Parameter(typeof(IEnumerable <object>), "list");

            ParameterExpression itemParam         = Expression.Parameter(tSource, "item");
            Expression          keySelectorSource = itemParam;

            if (tSource != SourceOf(resultOperator.GroupBy.KeySelector))
            {
                keySelectorSource = Expression.MakeMemberAccess(itemParam,
                                                                tSource.GetMember(
                                                                    ((QuerySourceReferenceExpression)
                                                                     resultOperator.GroupBy.KeySelector).ReferencedQuerySource.
                                                                    ItemName)[0]);
            }


            Expression keySelector = new GroupByKeySelectorVisitor(keySelectorSource).Visit(resultOperator.GroupBy.KeySelector);

            Expression elementSelectorSource = itemParam;

            if (tSource != SourceOf(resultOperator.GroupBy.ElementSelector))
            {
                elementSelectorSource = Expression.MakeMemberAccess(itemParam,
                                                                    tSource.GetMember(
                                                                        ((QuerySourceReferenceExpression)
                                                                         resultOperator.GroupBy.ElementSelector).ReferencedQuerySource.
                                                                        ItemName)[0]);
            }

            Expression elementSelector = new GroupByKeySelectorVisitor(elementSelectorSource).Visit(resultOperator.GroupBy.ElementSelector);

            var groupByMethod = EnumerableHelper.GetMethod("GroupBy",
                                                           new[] { typeof(IEnumerable <>), typeof(Func <,>), typeof(Func <,>) },
                                                           new[] { tSource, tKey, tElement });

            var castToItem = EnumerableHelper.GetMethod("Cast", new[] { typeof(IEnumerable) }, new[] { tSource });

            var toList = EnumerableHelper.GetMethod("ToList", new[] { typeof(IEnumerable <>) }, new[] { resultOperator.GroupBy.ItemType });

            LambdaExpression keySelectorExpr = Expression.Lambda(keySelector, itemParam);

            LambdaExpression elementSelectorExpr = Expression.Lambda(elementSelector, itemParam);

            Expression castToItemExpr = Expression.Call(castToItem, listParameter);

            var groupByExpr = Expression.Call(groupByMethod, castToItemExpr, keySelectorExpr, elementSelectorExpr);

            var toListExpr = Expression.Call(toList, groupByExpr);

            var lambdaExpr = Expression.Lambda(toListExpr, listParameter);

            tree.AddListTransformer(lambdaExpr);
        }
Пример #4
0
        public void Process(AggregateResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
        {
            var inputType       = resultOperator.Accumulator.Parameters[1].Type;
            var accumulatorType = resultOperator.Accumulator.Parameters[0].Type;
            var inputList       = Expression.Parameter(typeof(IEnumerable <>).MakeGenericType(typeof(object)), "inputList");

            var castToItem     = EnumerableHelper.GetMethod("Cast", new[] { typeof(IEnumerable) }, new[] { inputType });
            var castToItemExpr = Expression.Call(castToItem, inputList);

            MethodCallExpression call;

            if (resultOperator.ParseInfo.ParsedExpression.Arguments.Count == 2)
            {
                var aggregate = ReflectionHelper.GetMethodDefinition(() => Enumerable.Aggregate <object>(null, null));
                aggregate = aggregate.GetGenericMethodDefinition().MakeGenericMethod(inputType);

                call = Expression.Call(
                    aggregate,
                    castToItemExpr,
                    resultOperator.Accumulator
                    );
            }
            else if (resultOperator.ParseInfo.ParsedExpression.Arguments.Count == 3)
            {
                var aggregate = ReflectionHelper.GetMethodDefinition(() => Enumerable.Aggregate <object, object>(null, null, null));
                aggregate = aggregate.GetGenericMethodDefinition().MakeGenericMethod(inputType, accumulatorType);

                call = Expression.Call(
                    aggregate,
                    castToItemExpr,
                    resultOperator.OptionalSeed,
                    resultOperator.Accumulator
                    );
            }
            else
            {
                var selectorType = resultOperator.OptionalSelector.Type.GetGenericArguments()[2];
                var aggregate    = ReflectionHelper.GetMethodDefinition(() => Enumerable.Aggregate <object, object, object>(null, null, null, null));
                aggregate = aggregate.GetGenericMethodDefinition().MakeGenericMethod(inputType, accumulatorType, selectorType);

                call = Expression.Call(
                    aggregate,
                    castToItemExpr,
                    resultOperator.OptionalSeed,
                    resultOperator.Accumulator,
                    resultOperator.OptionalSelector
                    );
            }

            tree.AddListTransformer(Expression.Lambda(call, inputList));
        }
Пример #5
0
        public void Process(AnyResultOperator anyOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
        {
            if (tree.IsRoot)
            {
                tree.AddTakeClause(tree.TreeBuilder.Constant(1));

                Expression <Func <IEnumerable <object>, bool> > x = l => l.Any();
                tree.AddListTransformer(x);
            }
            else
            {
                tree.SetRoot(tree.TreeBuilder.Exists((HqlQuery)tree.Root));
            }
        }
Пример #6
0
        public void Process(AggregateFromSeedResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
        {
            var inputExpr       = ((StreamedSequenceInfo)queryModelVisitor.PreviousEvaluationType).ItemExpression;
            var inputType       = inputExpr.Type;
            var paramExpr       = Expression.Parameter(inputType, "item");
            var accumulatorFunc = Expression.Lambda(
                ReplacingExpressionTreeVisitor.Replace(inputExpr, paramExpr, resultOperator.Func.Body),
                resultOperator.Func.Parameters[0],
                paramExpr);

            var accumulatorType = resultOperator.Func.Parameters[0].Type;
            var inputList       = Expression.Parameter(typeof(IEnumerable <>).MakeGenericType(typeof(object)), "inputList");

            var castToItem     = ReflectionCache.EnumerableMethods.CastDefinition.MakeGenericMethod(new[] { inputType });
            var castToItemExpr = Expression.Call(castToItem, inputList);

            MethodCallExpression call;

            if (resultOperator.OptionalResultSelector == null)
            {
                var aggregate = ReflectionCache.EnumerableMethods.AggregateWithSeedDefinition
                                .MakeGenericMethod(inputType, accumulatorType);

                call = Expression.Call(
                    aggregate,
                    castToItemExpr,
                    resultOperator.Seed,
                    accumulatorFunc
                    );
            }
            else
            {
                var selectorType = resultOperator.OptionalResultSelector.Type.GetGenericArguments()[2];
                var aggregate    = ReflectionCache.EnumerableMethods.AggregateWithSeedAndResultSelectorDefinition
                                   .MakeGenericMethod(inputType, accumulatorType, selectorType);

                call = Expression.Call(
                    aggregate,
                    castToItemExpr,
                    resultOperator.Seed,
                    accumulatorFunc,
                    resultOperator.OptionalResultSelector
                    );
            }

            tree.AddListTransformer(Expression.Lambda(call, inputList));
        }
Пример #7
0
        public void Process(ClientSideSelect resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
        {
            var inputType  = resultOperator.SelectClause.Parameters[0].Type;
            var outputType = resultOperator.SelectClause.Type.GetGenericArguments()[1];

            var inputList = Expression.Parameter(typeof(IEnumerable <>).MakeGenericType(inputType), "inputList");

            var selectMethod = ReflectionCache.EnumerableMethods.SelectDefinition.MakeGenericMethod(new[] { inputType, outputType });
            var toListMethod = ReflectionCache.EnumerableMethods.ToListDefinition.MakeGenericMethod(new[] { outputType });

            var lambda = Expression.Lambda(
                Expression.Call(toListMethod,
                                Expression.Call(selectMethod, inputList, resultOperator.SelectClause)),
                inputList);

            tree.AddListTransformer(lambda);
        }
Пример #8
0
        public void Process(AllResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
        {
            tree.AddWhereClause(tree.TreeBuilder.BooleanNot(
                                    HqlGeneratorExpressionTreeVisitor.Visit(resultOperator.Predicate, queryModelVisitor.VisitorParameters).
                                    ToBooleanExpression()));

            if (tree.IsRoot)
            {
                tree.AddTakeClause(tree.TreeBuilder.Constant(1));

                Expression <Func <IEnumerable <object>, bool> > x = l => !l.Any();
                tree.AddListTransformer(x);
            }
            else
            {
                tree.SetRoot(tree.TreeBuilder.BooleanNot(tree.TreeBuilder.Exists((HqlQuery)tree.Root)));
            }
        }
Пример #9
0
        public void Process(AnyResultOperator anyOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
        {
            if (tree.IsRoot)
            {
                tree.AddTakeClause(tree.TreeBuilder.Constant(1));

                Expression <Func <IEnumerable <object>, bool> > x = l => l.Any();
                tree.AddListTransformer(x);

                // NH-3850: Queries with polymorphism yields many results which must be combined.
                Expression <Func <IEnumerable <bool>, bool> > px = l => l.Any(r => r);
                tree.AddPostExecuteTransformer(px);
            }
            else
            {
                tree.SetRoot(tree.TreeBuilder.Exists((HqlQuery)tree.Root));
            }
        }
Пример #10
0
        public void Process(AllResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
        {
            tree.AddWhereClause(tree.TreeBuilder.BooleanNot(
                                    HqlGeneratorExpressionVisitor.Visit(resultOperator.Predicate, queryModelVisitor.VisitorParameters).
                                    ToBooleanExpression()));

            if (tree.IsRoot)
            {
                tree.AddTakeClause(tree.TreeBuilder.Constant(1));

                Expression <Func <IEnumerable <object>, bool> > x = l => !l.Any();
                tree.AddListTransformer(x);

                // NH-3850: Queries with polymorphism yields many results which must be combined.
                Expression <Func <IEnumerable <bool>, bool> > px = l => l.All(r => r);
                tree.AddPostExecuteTransformer(px);
            }
            else
            {
                tree.SetRoot(tree.TreeBuilder.BooleanNot(tree.TreeBuilder.Exists((HqlQuery)tree.Root)));
            }
        }
Пример #11
0
 public void Process(ClientSideSelect2 resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
 {
     tree.AddListTransformer(resultOperator.SelectClause);
 }