LINQ GroupBy孩子的孩子

时间:2014-11-28 10:33:30

标签: c# linq

我不确定这个问题是否重复,因为这是我努力寻找的东西,因为基本上我不知道什么是功能名称。所以,如果是这样,我很抱歉。

举例说明一个团队有人并且该人有多个电话号码,我想按号码分组,并且仍然保留与团队相关的所有信息。所以基本上使属性Number成为我的groupby的关键。

public class PhoneNumber
{
   public string Number { get; set; }
}

public class Person
{
  public List<PhoneNumber> PhoneNumbers { get; set; }
}

public class Team
{
  public List<Person> Persons{ get; set; }
}

IEnumerable<Team> teams = new List<Team>();

所以我想做类似的事情:

Team.Persons.GroupBy(i=> i.PhoneNumbers.Number)

显然我不能,因为PhoneNumbers是一个List

最终结果应该是

  • Number1234 - &gt; Team1,Team2
  • Number5678 - &gt; Team1,Team2,Team3

其中NumberX是groupby键,TeamX包含与拥有该电话号码的成员的团队相关联的信息。

可能我的方法在这个例子中完全不合适,所以任何反馈都会受到赞赏。

2 个答案:

答案 0 :(得分:4)

你基本上需要展平结果,这样你就可以得到团队/数字对,然后你可以按数字分组。例如:

// IEnumerable<IGrouping<string, Team>>
var grouped = from team in teams
              from person in team.Persons
              from number in person.PhoneNumbers
              group team by number.Number;

您可能还想考虑创建Lookup而不是分组:

// ILookup<string, Team>
var lookup = (from team in teams
              from person in team.Persons
              from number in person.PhoneNumbers
              select new { team, number }).ToLookup(p => p.number.Number,
                                                    p => p.team);

通过查找,您可以执行以下操作:

var number = "...";
foreach (var team in lookup[number])
{
    ...
}

...如果您要求拥有未知电话号码的团队,它将有助于返回空序列。

答案 1 :(得分:1)

其中一种方法是选择所有电话号码及其相关团队,然后您可以进行分组:

var teamsGrouppedByPhoneNumbers = (from t in Teams
from p in t.Persons
from pn in p.PhoneNumbers
select new { Team = t, PhoneNumber = pn })
.GroupBy(x => x.PhoneNumber.Number)
.ToList();