using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Dynamic; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Threading; using System.Web; namespace EnVisage.Code.Extensions { public class GroupResult { public string Field { get; set; } public object Key { get; set; } public int Count { get; set; } public IEnumerable Items { get; set; } public IEnumerable SubGroups { get; set; } public override string ToString() { return string.Format("{0} ({1})", Key, Count); } } public static class EnumerableExtensions { public static IEnumerable GroupByMany(this IEnumerable elements, params string[] groupSelectors) { //var selectors = new List>(groupSelectors.Length); var dict = new Dictionary>(); foreach (var selector in groupSelectors) { var lambda = System.Linq.Dynamic.DynamicExpression.ParseLambda(typeof(TElement), typeof(object), selector); //selectors.Add((Func)l.Compile()); dict.Add(selector, (Func)lambda.Compile()); } return elements.GroupByMany(dict); } private static IEnumerable GroupByMany(this IEnumerable elements, IEnumerable>> groupSelectors) { if (groupSelectors.Any()) { var selector = groupSelectors.First(); var nextSelectors = groupSelectors.Skip(1); //reduce the list recursively until zero return elements.GroupBy(selector.Value).Select( group => new GroupResult { Field = selector.Key, Key = group.Key, Count = group.Count(), Items = group.OrderBy(selector.Value), SubGroups = group.GroupByMany(nextSelectors) }); } else { return null; } } public static IQueryable Select(this IQueryable source, string selector, params object[] values) { if (source == null) throw new ArgumentNullException("source"); if (selector == null) throw new ArgumentNullException("selector"); LambdaExpression lambda = System.Linq.Dynamic.DynamicExpression.ParseLambda(source.ElementType, typeof(TResult), selector, values); return source.Provider.CreateQuery( Expression.Call( typeof(Queryable), "Select", new System.Type[] { source.ElementType, typeof(TResult) }, source.Expression, Expression.Quote(lambda))); } public static string GetAsCommaSeparatedList(this IEnumerable source) { string result = String.Empty; if (source != null) { result = string.Join("','", source); if (result.Length > 0) result = String.Format("'{0}'", result); } return result; } } }