//private IQueryable BuildGroupBy(IQueryable<TSource> query) //{ // MakeGroupByExpression(GroupingKeys.ToArray(), out Type keyType, out var expr); // IQueryable result = (IQueryable)TypicalLinqMethods.QueryableGroupBy // .MakeGenericMethod(typeof(TSource), keyType) // .Invoke(null, new object[] { query, expr }); // return result; //} internal static LambdaExpression MakeGroupByExpression(GroupingKey[] keys) { var parameter = Expression.Parameter(typeof(TSource)); int count = keys.Length; Type keyType; if (count == 0) { keys = new GroupingKey[] { GroupingKey.NoGroupingKey }; count = 1; } keyType = Type.GetType(typeof(GroupingKey).FullName + "`" + count, false); if (keyType == null) { throw new InvalidOperationException("Too many grouping keys, at most 9 keys are allowed."); } keyType = keyType.MakeGenericType(keys.Select(o => o.SourceSelector.ReturnType).ToArray()); MemberBinding[] bindings = new MemberBinding[count]; for (int i = 0; i < count; i++) { var key = keys[i]; key.PropertyName = "Item" + (i + 1); bindings[i] = Expression.Bind(keyType.GetProperty(key.PropertyName), AggregationHelper.ExtractExpression(key.SourceSelector, parameter)); } return(Expression.Lambda(Expression.MemberInit(Expression.New(keyType), bindings), parameter)); }
public AggregationHelper <TSource, TResult> GroupBy <TValue>(Expression <Func <TSource, TValue> > keySelector) { foreach (var key in AggregationHelper.ExtractGroupingKeys(keySelector, typeof(TResult))) { _mappings.Add(key); } return(this); }
public AggregationResult <T> Lift <TKey>(Expression <Func <T, TKey> > keySelector, Func <T, string> label) { if (keySelector == null) { throw new ArgumentNullException(nameof(keySelector)); } var keys = AggregationHelper.ExtractGroupingKeys(keySelector, typeof(T)); Lift(keys, AggregationLevel.Subtotal, label); return(this); }
private void Lift(GroupingKey[] keys, AggregationLevel level, Func <T, string> label) { if (keys != null) { for (int i = 0; i < keys.Length; i++) { var key = keys[i]; LambdaExpression source = key.SourceSelector, result = key.ResultSelector; if (source != null && LiftModelToViewItem(ref source) || result != null && LiftModelToViewItem(ref result)) { keys[i] = new GroupingKey(source, result); } } } else { keys = new GroupingKey[] { GroupingKey.NoGroupingKey } }; LambdaExpression groupBy = AggregationHelper <AggregationResultItem <T> > .MakeGroupByExpression(keys); var temp = TypicalLinqMethods.EnumerableGroupBy .MakeGenericMethod(typeof(AggregationResultItem <T>), groupBy.ReturnType) .Invoke(null, new object[] { Items, groupBy.Compile() }); var selectItem = MakeSelectExpression(groupBy, keys, level, label); MethodInfo method = TypicalLinqMethods.EnumerableSelect .MakeGenericMethod(selectItem.Parameters[0].Type, typeof(AggregationResultItem <T>)); var coll = (IEnumerable <AggregationResultItem <T> >)method.Invoke(null, new object[] { temp, selectItem.Compile() }); _items.Clear(); _items.AddRange(coll); AppendGeneration(); }
public static AggregationResult <T> Create <TSource>(IEnumerable <T> query, AggregationHelper <TSource, T> helper, Func <T, string> label) { return(Create(query, label, helper.Functions)); }
public static AggregationResult <T> Create <TSource>(IQueryable <TSource> query, AggregationHelper <TSource, T> helper, Func <T, string> label) { return(Create(helper.GetQuery(query).AsEnumerable(), helper, label)); }