2017-04-25 48 views
0

我需要按列表对象的动态属性值进行分组。按列表对象组动态属性值c#

我的对象是:

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子句中使用(选择是我的lambda表达式):

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

但我不能创造这个lambda表达式。我获得的第二线的错误:

“类型”的实例属性未设置为类型“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); 

任何人都可以帮到我吗?

+0

首先,你想达到什么目的?按照他们所拥有的联系信息类型对他们进行分组?如果一个人拥有“网站”和“地址”会怎么样?它应该去哪个组? –

+0

动态构建'Expression'而不是让C#编译器为你做这件事的任何理由是什么? –

+0

我试图通过很多过滤器来实现一组结果。在这种情况下,我可以通过多种类型的联系人将人员列表分组(例如,“site”和“address”组成的组)。 – Jcbo

回答

0

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

  1. 获取所有联系类型。
  2. 根据每个联系人类型创建一个词典,其中包含该类型下列出的任何联系人的所有人员。

这可以用下面的代码来完成:

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是包含作为关键接触型字典和作为值的接触类型下的人的列表。