2014-11-28 3 views
1

Я не уверен, что этот вопрос является дубликатом или нет, поскольку это то, что я много искал, чтобы искать, поскольку в основном я не знаю, как будет функциональное имя. Так что, если это так, мои извинения.LINQ GroupBy дочерний элемент ребенка

Приведите пример, когда у команды есть люди, и у человека есть несколько телефонных номеров, я хотел бы сгруппировать по номеру и все еще поддерживать всю информацию, связанную с командой. Поэтому в основном сделайте свойство Number ключевым для моей группы.

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)

, который, очевидно, я не могу, потому что номера телефонов является списком

Конечный результат должен быть что-то вроде

  • Номер1234 -> Team1, Team2
  • Number5678 -> Команда1, team2, Team3

Где NumberX ключ GroupBy и TeamX содержит информацию, связанную с командой, которая имеет элемент с этим телефоном.

Возможно, мой подход совершенно неуместен в этом примере, поэтому любая обратная связь будет оценена по достоинству.

ответ

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]) 
{ 
    ... 
} 

. .. и он поможет вернуть пустую последовательность, если вы попросите команды с неизвестным номером телефона.

+0

Это было именно то, что я искал! Спасибо, Джон. Похоже, что поиск выглядит ближе к тому, что я хочу использовать. Одна вещь, которую я заметил, что последняя строка должна, вероятно, быть – rjso

+0

, выбрать новый {номер, команда}). ToLookup (p => p.number.Number, p => p.team); кроме этого места на – rjso

+0

@rjso: Почему? Неважно, какой порядок свойства анонимного типа здесь ... –

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(); 
Смежные вопросы