我要为GroupBy构建一个动态表达式树。我想要实现的就是这样。
var NestedGrouped = listOfPerson.GroupByMany(x => x.Name,x=>x.Age).ToList();
我的人员类如: -
class Person
{
public string Name{ get; set; }
public int Age{ get; set; }
public float Salary{ get; set; }
}
public class GroupResult
{
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 MyEnumerableExtensions
{
public static IEnumerable<GroupResult> GroupByMany<TElement>(
this IEnumerable<TElement> elements,
params Func<TElement, object>[] groupSelectors)
{
if (groupSelectors.Length > 0)
{
var selector = groupSelectors.First();
//reduce the list recursively until zero
var nextSelectors = groupSelectors.Skip(1).ToArray();
return
elements.GroupBy(selector).Select(
g => new GroupResult
{
Key = g.Key,
Count = g.Count(),
Items = g,
SubGroups = g.GroupByMany(nextSelectors)
});
}
else
return null;
}
}
对于单个属性我能够构建表达式,但我想做GROUPBY 具有多个列,如上所示。 对于单一财产: -
ParameterExpression parameter = Expression.Parameter(typeof(Person), "lambdaKey");
var menuProperty = Expression.PropertyOrField(parameter, "Name");
var lambda = Expression.Lambda<Func<Person, string>>(menuProperty, parameter);
var selector = lambda.Compile();
var result = P1.GroupByMany(selector);// P1 is list of PERSON
如何在表达式树中添加多个列(例如(x =&gt; x.Name,x =&gt; x.Age))。
请帮忙。在此先感谢。
答案 0 :(得分:1)
GroupByMany()
接受委托数组,每个密钥一个委托。因此,您需要为每个键创建和编译单独的表达式。
代码看起来像:
private static Func<TElement, object> CreateSelector<TElement>(string key)
{
var parameter = Expression.Parameter(typeof(TElement), "lambdaKey");
var property = Expression.PropertyOrField(parameter, key);
var lambda = Expression.Lambda<Func<TElement, string>>(property, parameter);
return lambda.Compile();
}
public static IEnumerable<GroupResult> GroupByMany<TElement>(
this IEnumerable<TElement> elements,
params string[] groupKeys)
{
return elements.GroupByMany(groupKeys.Select(CreateSelector<TElement>).ToArray());
}