Если у вас есть отношение «один ко многим» с использованием внешнего ключа, и вам нужны элементы с их подэлементами, например, «Школы с их учениками», «Клиенты с их заказами», «Главные группы» с их подгруппами, тогда вы можете использоватьпросто выберите, чтобы получить свой результат, или используйте GroupJoin
Select
var result = mainGroupCollection.Select(mainGroup => new MainGroupViewModel
{
Id = mainGroup.Id,
Name = mainGroup.Name,
...
// Keep only the Groups of this MainGroup, using foreign key
Groups = groupCollection
.Where(group => group.MainGroupId == mainGroup.Id)
.Select(group => new GroupViewModel
{
Id = group.Id,
Name = group.Name,
...
// Keep only the subGroups of this Group, using foreign key
SubGroups = subGroupCollection
.Where(subGroup => subGroup.GroupId == group.Id)
.Select(subGroup => new SubGroupViewModel
{
Id = group.Id,
Name = group.Name,
...
})
.ToList(),
})
.ToList(),
});
Хотя этот метод работает, он не очень эффективен, потому что для каждого элемента вmainGroupCollection он должен перечислять по всей GroupCollection, а для каждого элемента он должен перечислять по всей SubGroupCollection.
В зависимости от того, какую СУБД вы используете при запросе из базы данных, это не является большой проблемой.Тем не менее, я бы пошел для GroupJoin
GroupJoin
Enumerable.GroupJoin гораздо более эффективен (или эквивалент IQueryable).Версия Enumerable использует словарь, чтобы увидеть, нашел ли он элемент с таким идентификатором, поэтому ему не нужно перечислять более одного раза по каждой коллекции.
// GroupJoin the mainGroupCollection with the groupCollection:
var result = mainGroupCollection.GroupJoin(groupCollection,
mainGroup = mainGroup.Id, // from every mainGroup take the primary key
group => group.MainGroupId, // from every group take the foreign key
// ResultSelector: for every mainGroup and its groups make one MainGroupViewModel
(mainGroup, groupsOfThisMainGroup) => new MainGroupViewModel
{
Id = mainGroup.Id,
Name = mainGroup.Name,
...
// for the Groups: GroupJoin the groups of this main group with the subGroups
Groups = groupsOfThisMainGroup.GroupJoin(subGroupCollection,
groupOfThisMainGroup => groupOfThisMainGroup.Id,
subGroup => subGroup.GroupId,
// result selector
(group, subGroupsOfThisGroup) => new GroupViewModel
{
Id = group.Id,
Name = group.Name,
SubGroups = subGroupsOfThisGroup.Select(subGroup => new SubGroupViewModel
{
Id = subGroup.Id,
Name = subGroup.Name,
...
})
.ToList(),
})
.ToList(),
});