按动态属性值c#按列表对象分组

时间:2017-04-25 22:48:49

标签: c# lambda

我需要通过动态属性值按列表对象进行分组。

我的目标是:

public class Person
{
    public string Name {get;set;}
    public List<Contact> Contacts {get;set;}
}

public class Contact
{
    public string Type {get;set;}
    public string Value {get;set;}
}

我需要按联系类型分组(例如:“网站”,“地址”)

我尝试创建一个lambda表达式来表示搜索groupBy子句中使用的联系人类型(selector是我的lambda表达式):

persons.GroupBy(selector).Select(
    g => new GroupResult<TElement>
    {
        Key = g.Key,
        Items = g,
        SubGroups = g.GroupByMany(nextSelectors)
    });

但我无法创建这个lambda表达式。我在第二行收到错误:

  

“Type”实例属性未设置为“ConsoleApplication1.Person”类型。

我如何在人员名单中表示“网站”联系方式?

var parameterExp = Expression.Parameter(typeof(TElement), "Contacts");
var propertyExp = Expression.Property(parameterExp, "Type");
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant("Site", typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);

Expression<Func<TElement, object>> predicate = Expression.Lambda<Func<TElement, object>>
 (containsMethodExp, parameterExp);

任何人都可以帮助我?

1 个答案:

答案 0 :(得分:0)

您不需要自己创建表达式。解决这个问题的一种方法是将你想要做的事分成两部分:

  1. 获取所有联系类型。
  2. 根据每种联系类型创建一个字典,其中包含该类型下列出的任何联系人。
  3. 可以使用以下代码完成此操作:

    var contactTypes = persons.SelectMany(p => p.Contacts.Select(c => c.Type)).GroupBy(c => c).ToDictionary(c => c.Key);
    var groupedPersons = contactTypes.ToDictionary(t => t.Key, t => persons.Where(p => p.Contacts.Any(c => c.Type == t.Key)).ToList());
    

    groupedPersons 是一个字典,其中包含联系人类型的关键字和值,表示该联系人类型下的人员列表。