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 = ReverseResolvingExpressionTreeVisitor.ReverseResolve(selector, keySelector); var elementSelectorExpr = ReverseResolvingExpressionTreeVisitor.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 override StreamedValue ExecuteInMemory <T>(StreamedSequence input) { var sequence = input.GetTypedSequence <T>(); var predicateLambda = ReverseResolvingExpressionTreeVisitor.ReverseResolve(input.DataInfo.ItemExpression, Predicate); var predicate = (Func <T, bool>)predicateLambda.Compile(); var result = sequence.All(predicate); return(new StreamedValue(result, (StreamedValueInfo)base.GetOutputDataInfo(input.DataInfo))); }
/// <inheritdoc cref="ResultOperatorBase.ExecuteInMemory" /> public override StreamedValue ExecuteInMemory <T>(StreamedSequence input) { var sequence = input.GetTypedSequence <T>(); var funcLambda = ReverseResolvingExpressionTreeVisitor.ReverseResolveLambda(input.DataInfo.ItemExpression, Func, 1); var func = (Func <T, T, T>)funcLambda.Compile(); var result = sequence.Aggregate(func); return(new StreamedValue(result, (StreamedValueInfo)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); ReverseResolvingExpressionTreeVisitor.ReverseResolve(_itemExpression, resolvedExpression); }
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); ReverseResolvingExpressionTreeVisitor.ReverseResolveLambda(_itemExpression, resolvedExpression, -1); }
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 = ReverseResolvingExpressionTreeVisitor.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 = ReverseResolvingExpressionTreeVisitor.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 = ReverseResolvingExpressionTreeVisitor.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) { var inputSequence = input.GetTypedSequence <TSource>(); var keySelectorLambda = ReverseResolvingExpressionTreeVisitor.ReverseResolve(input.DataInfo.ItemExpression, KeySelector); var keySelector = (Func <TSource, TKey>)keySelectorLambda.Compile(); var elementSelectorLambda = ReverseResolvingExpressionTreeVisitor.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 = ReverseResolvingExpressionTreeVisitor.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) { var sequence = input.GetTypedSequence <TInput>(); var seed = GetConstantSeed <TAggregate>(); var funcLambda = ReverseResolvingExpressionTreeVisitor.ReverseResolveLambda(input.DataInfo.ItemExpression, Func, 1); var func = (Func <TAggregate, TInput, TAggregate>)funcLambda.Compile(); var aggregated = sequence.Aggregate(seed, func); var outputDataInfo = (StreamedValueInfo)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)); } }