90 lines
3.3 KiB
C#
90 lines
3.3 KiB
C#
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<GroupResult> SubGroups { get; set; }
|
|
public override string ToString() { return string.Format("{0} ({1})", Key, Count); }
|
|
}
|
|
|
|
|
|
public static class EnumerableExtensions
|
|
{
|
|
public static IEnumerable<GroupResult> GroupByMany<TElement>(this IEnumerable<TElement> elements, params string[] groupSelectors)
|
|
{
|
|
//var selectors = new List<Func<TElement, object>>(groupSelectors.Length);
|
|
var dict = new Dictionary<string, Func<TElement, object>>();
|
|
foreach (var selector in groupSelectors)
|
|
{
|
|
var lambda = System.Linq.Dynamic.DynamicExpression.ParseLambda(typeof(TElement), typeof(object), selector);
|
|
//selectors.Add((Func<TElement, object>)l.Compile());
|
|
dict.Add(selector, (Func<TElement, object>)lambda.Compile());
|
|
}
|
|
|
|
return elements.GroupByMany(dict);
|
|
}
|
|
|
|
private static IEnumerable<GroupResult> GroupByMany<TElement>(this IEnumerable<TElement> elements, IEnumerable<KeyValuePair<string, Func<TElement, object>>> 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<TResult> Select<TResult>(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<TResult>(
|
|
Expression.Call(
|
|
typeof(Queryable), "Select",
|
|
new System.Type[] { source.ElementType, typeof(TResult) },
|
|
source.Expression, Expression.Quote(lambda)));
|
|
}
|
|
|
|
public static string GetAsCommaSeparatedList(this IEnumerable<Guid> source)
|
|
{
|
|
string result = String.Empty;
|
|
|
|
if (source != null)
|
|
{
|
|
result = string.Join("','", source);
|
|
if (result.Length > 0)
|
|
result = String.Format("'{0}'", result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
} |