构建具有多个属性的动态组选择器表达式树 [英] Building Dynamic GroupBy Selector Expression Tree With Multiple Properties

查看:212
本文介绍了构建具有多个属性的动态组选择器表达式树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要为GroupBy构建动态表达式树。我想要实现的就是这样。

  var NestedGrouped = listOfPerson.GroupByMany(x => x.Name,x => x.Age).ToList ); 

我的人员类别如下: -

  class Person 
{
public string Name {get;组; }
public int Age {get;组; }
public float Salary {get;组; }
}
public class GroupResult
{
public object Key {get;组; }
public int Count {get;组; }
public IEnumerable Items {get;组; }
public IEnumerable< GroupResult>子组{get;组; }
public override string ToString()
{return string.Format({0}({1}),Key,Count); }
}
public static class MyEnumerableExtensions
{
public static IEnumerable< GroupResult> GroupByMany< TElement>(
这个IEnumerable< TElement>元素,
params Func< TElement,object> [] groupSelectors)
{
if(groupSelectors.Length> 0)
{
var selector = groupSelectors.First();

//递归减少列表直到零
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
返回null;
}
}

对于单个属性我可以构建表达式我想做GROUPBY
与多个列,如上所示。
FOR SINGLE PROPERTY: -

  ParameterExpression parameter = Expression.Parameter(typeof(Person),lambdaKey); 
var menuProperty = Expression.PropertyOrField(parameter,Name);
var lambda = Expression.Lambda var selector = lambda.Compile();
var result = P1.GroupByMany(selector); // P1是PERSON的列表

如何在表达式树中添加多个列(例如(x => x.Name,x => x.Age))。

请帮助。感谢Advance。

解决方案

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>(
此IEnumerable< TElement>元素,
params string [] groupKeys)
{
返回元素.GroupByMany(groupKeys.Select(CreateSelector< TElement>))。 ToArray的());
}


I am to build a dynamic Expression Tree for GroupBy. All i want to achieve is like this.

var NestedGrouped = listOfPerson.GroupByMany(x => x.Name,x=>x.Age).ToList(); 

My Person Class is like :-

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;
        }
    }

For Single Property I am able to build the expression but i want to do GROUPBY with multiple columns as shown above. FOR SINGLE PROPERTY :-

 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

How to ADD multiple columns in Expression Tree (e.g (x => x.Name,x=>x.Age)).
Please Help. Thanks in Advance.

解决方案

GroupByMany() accepts array of delegates, one delegate for each key. So, what you need is to create and compile a separate expression for each key.

The code could look something like:

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());
}

这篇关于构建具有多个属性的动态组选择器表达式树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆