嵌套3层LINQ查询

时间:2014-05-12 19:53:11

标签: c# .net linq lambda

我有多个Person对象,每个对象可能包含0个或更多个Email对象。我需要搜索针对人员集合的人员,并查找记录,其中Person中包含的电子邮件地址也存在于人员记录集合中的任何一个中。然后我可以采取行动合并这些记录

下面的汇总类结构:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IList<Email> Emails { get; set; }
}


public class Email
{
    public string Label { get; set; }
    public string Address{ get; set; }
    public bool IsPrimary { get; set; }
}

public class Person { public int Id { get; set; } public string Name { get; set; } public IList<Email> Emails { get; set; } } public class Email { public string Label { get; set; } public string Address{ get; set; } public bool IsPrimary { get; set; } } 我需要找到一个列表并找到具有相同电子邮件地址的人。但是,我无法弄清楚如何构造一个匹配Person的LINQ查询并循环通过一个Person of obejcts并比较电子邮件地址?

理想情况下,这将是一个lambda,但很想知道创建它的一步一步的过程。

1 个答案:

答案 0 :(得分:5)

您可以将人员投射到电子邮件 - 人物对的序列,并通过电子邮件地址对这些序列进行分组。在这种情况下,每个组将拥有共享相同电子邮件地址(组的密钥)的人员:

people.SelectMany(p => p.Emails.Select(e => new { e.Address, Person = p }))
      .GroupBy(x => x.Address)
      .Select(g => new { Address = g.Key, People = g.Select(x => x.Person) })

查询语法:

from p in people
from e in p.Emails
select new { e.Address, Person = p } into x
group x by x.Address into g
select new {
   Address = g.Key,
   People = g.Select(x => x.Person)
}

注意:如果您需要将整个电子邮件设置为唯一身份,请覆盖Equals的{​​{1}}和GetHashCode方法,以便按照其字段的值而不是按字段的值比较此类的实例参考(或确保您在不同的人之间共享相同的电子邮件实例)。