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);
        }
Exemple #2
0
        /// <inheritdoc cref="ResultOperatorBase.ExecuteInMemory" />
        public override StreamedValue ExecuteInMemory <T> (StreamedSequence input)
        {
            ArgumentUtility.CheckNotNull("input", input);

            var sequence   = input.GetTypedSequence <T>();
            var funcLambda = ReverseResolvingExpressionVisitor.ReverseResolveLambda(input.DataInfo.ItemExpression, Func, 1);
            var func       = (Func <T, T, T>)funcLambda.Compile();
            var result     = sequence.Aggregate(func);

            return(new StreamedValue(result, GetOutputDataInfo(input.DataInfo)));
        }
        public void ReverseResolve_NonAccessibleReferenceExpression_Throws()
        {
            // itemExpression: new AnonymousType<Cook, Cook> ( a = [s1], b = [s2] )
            // resolvedExpression: [s3]
            // expected result: exception

            var fromClause3        = ExpressionHelper.CreateMainFromClause_Int("s3", typeof(Cook), ExpressionHelper.CreateQueryable <Cook>());
            var resolvedExpression = new QuerySourceReferenceExpression(fromClause3);

            ReverseResolvingExpressionVisitor.ReverseResolve(_itemExpression, resolvedExpression);
        }
Exemple #4
0
        /// <inheritdoc />
        public override AsyncStreamedValue ExecuteInMemory <T>(StreamedSequence input)
        {
            var sequence = input.GetTypedSequence <T>();

            var predicateLambda = ReverseResolvingExpressionVisitor.ReverseResolve(
                input.DataInfo.ItemExpression, Predicate);
            var predicate = (Func <T, bool>)predicateLambda.Compile();

            var result = sequence.All(predicate);

            return(new AsyncStreamedValue(Task.FromResult(result), GetOutputDataInfo(input.DataInfo)));
        }
        public void ReverseResolveLambda_InvalidPosition_TooSmall()
        {
            // itemExpression: new AnonymousType<Cook, Cook> ( a = [s1], b = [s2] )
            // resolvedExpression: (x, y) => 0
            // expected result: (x, input, y) => 0

            var parameter1         = Expression.Parameter(typeof(int), "x");
            var parameter2         = Expression.Parameter(typeof(string), "y");
            var resolvedExpression = Expression.Lambda(Expression.Constant(0), parameter1, parameter2);

            ReverseResolvingExpressionVisitor.ReverseResolveLambda(_itemExpression, resolvedExpression, -1);
        }
        /// <inheritdoc cref="ResultOperatorBase.ExecuteInMemory" />
        public override StreamedValue ExecuteInMemory <T> (StreamedSequence input)
        {
            ArgumentUtility.CheckNotNull("input", input);

            var sequence = input.GetTypedSequence <T> ();

            var predicateLambda = ReverseResolvingExpressionVisitor.ReverseResolve(input.DataInfo.ItemExpression, Predicate);
            var predicate       = (Func <T, bool>)predicateLambda.Compile();

            var result = sequence.All(predicate);

            return(new StreamedValue(result, GetOutputDataInfo(input.DataInfo)));
        }
        public void ReverseResolve_TopLevelReferenceExpression()
        {
            // itemExpression: new AnonymousType<Cook, Cook> ( a = [s1], b = [s2] )
            // resolvedExpression: [s1]
            // expected result: input => input.a

            var resolvedExpression = _querySource1;

            LambdaExpression lambdaExpression = ReverseResolvingExpressionVisitor.ReverseResolve(_itemExpression, resolvedExpression);

            var expectedExpression = ExpressionHelper.CreateLambdaExpression <AnonymousType <Cook, Cook>, Cook> (input => input.a);

            ExpressionTreeComparer.CheckAreEqualTrees(expectedExpression, lambdaExpression);
        }
        public void ReverseResolve_NoReferenceExpression()
        {
            // itemExpression: new AnonymousType<Cook, Cook> ( a = [s1], b = [s2] )
            // resolvedExpression: 0
            // expected result: input => 0

            var resolvedExpression = Expression.Constant(0);

            LambdaExpression lambdaExpression = ReverseResolvingExpressionVisitor.ReverseResolve(_itemExpression, resolvedExpression);

            var expectedExpression = ExpressionHelper.CreateLambdaExpression <AnonymousType <Cook, Cook>, int> (input => 0);

            ExpressionTreeComparer.CheckAreEqualTrees(expectedExpression, lambdaExpression);
        }
        public void ReverseResolve_MultipleNestedReferenceExpressions()
        {
            // itemExpression: new AnonymousType<Cook, Cook> ( a = [s1], b = [s2] )
            // resolvedExpression: [s1].ID + [s2].ID
            // expected result: input => input.a.ID + input.b.ID

            var resolvedExpression = ExpressionHelper.Resolve <Cook, Cook, int> (_fromClause1, _fromClause2, (s1, s2) => s1.ID + s2.ID);

            LambdaExpression lambdaExpression = ReverseResolvingExpressionVisitor.ReverseResolve(_itemExpression, resolvedExpression);

            var expectedExpression = ExpressionHelper.CreateLambdaExpression <AnonymousType <Cook, Cook>, int> (input => input.a.ID + input.b.ID);

            ExpressionTreeComparer.CheckAreEqualTrees(expectedExpression, lambdaExpression);
        }
        public StreamedSequence ExecuteGroupingInMemory <TSource, TKey, TElement> (StreamedSequence input)
        {
            ArgumentUtility.CheckNotNull("input", input);

            var inputSequence = input.GetTypedSequence <TSource> ();

            var keySelectorLambda = ReverseResolvingExpressionVisitor.ReverseResolve(input.DataInfo.ItemExpression, KeySelector);
            var keySelector       = (Func <TSource, TKey>)keySelectorLambda.Compile();

            var elementSelectorLambda = ReverseResolvingExpressionVisitor.ReverseResolve(input.DataInfo.ItemExpression, ElementSelector);
            var elementSelector       = (Func <TSource, TElement>)elementSelectorLambda.Compile();

            var resultSequence = inputSequence.GroupBy(keySelector, elementSelector);

            return(new StreamedSequence(resultSequence.AsQueryable(), (StreamedSequenceInfo)GetOutputDataInfo(input.DataInfo)));
        }
        public void ReverseResolveLambda()
        {
            // itemExpression: new AnonymousType<Cook, Cook> ( a = [s1], b = [s2] )
            // resolvedExpression: (x, y) => 0
            // expected result: (x, input, y) => 0

            var parameter1         = Expression.Parameter(typeof(int), "x");
            var parameter2         = Expression.Parameter(typeof(string), "y");
            var resolvedExpression = Expression.Lambda(Expression.Constant(0), parameter1, parameter2);

            var lambdaExpression = ReverseResolvingExpressionVisitor.ReverseResolveLambda(_itemExpression, resolvedExpression, 1);

            var expectedExpression = ExpressionHelper.CreateLambdaExpression <int, AnonymousType <Cook, Cook>, string, int> ((x, input, y) => 0);

            ExpressionTreeComparer.CheckAreEqualTrees(expectedExpression, lambdaExpression);
        }
        /// <summary>
        /// Executes the aggregating operation in memory.
        /// </summary>
        /// <typeparam name="TInput">The type of the source items.</typeparam>
        /// <typeparam name="TAggregate">The type of the aggregated items.</typeparam>
        /// <typeparam name="TResult">The type of the result items.</typeparam>
        /// <param name="input">The input sequence.</param>
        /// <returns>A <see cref="StreamedValue"/> object holding the aggregated value.</returns>
        public StreamedValue ExecuteAggregateInMemory <TInput, TAggregate, TResult> (StreamedSequence input)
        {
            ArgumentUtility.CheckNotNull("input", input);

            var sequence   = input.GetTypedSequence <TInput> ();
            var seed       = GetConstantSeed <TAggregate> ();
            var funcLambda = ReverseResolvingExpressionVisitor.ReverseResolveLambda(input.DataInfo.ItemExpression, Func, 1);
            var func       = (Func <TAggregate, TInput, TAggregate>)funcLambda.Compile();

            var aggregated     = sequence.Aggregate(seed, func);
            var outputDataInfo = GetOutputDataInfo(input.DataInfo);

            if (OptionalResultSelector == null)
            {
                return(new StreamedValue(aggregated, outputDataInfo));
            }
            else
            {
                var resultSelector = (Func <TAggregate, TResult>)OptionalResultSelector.Compile();
                var result         = resultSelector(aggregated);
                return(new StreamedValue(result, outputDataInfo));
            }
        }