예제 #1
0
        //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));
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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();
        }
예제 #5
0
 public static AggregationResult <T> Create <TSource>(IEnumerable <T> query, AggregationHelper <TSource, T> helper, Func <T, string> label)
 {
     return(Create(query, label, helper.Functions));
 }
예제 #6
0
 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));
 }