Как заказать детские коллекции объектов в EF
У меня есть следующий запрос:
public IEnumerable<Team> GetAllTeamsWithMembers(int ownerUserId)
{
return _ctx.Teams
.Include(x => x.TeamMembers)
.Where(x => x.UserId == ownerUserId)
.OrderBy(x => x.Name).ToList();
}
Как мне упорядочить команды по их имени, а затем все дочерние члены каждой команды отсортированы по их имени?
Кажется, что для этого мне нужно создать новый класс DTO и использовать select. Я хотел бы использовать созданные EF-объекты, в этом случае Team имеет свойство навигации для членов. Я возвращаю IEnumerable<Team>
из моего уровня репозитория.
Кажется, что нет аккуратного способа упорядочивания дочерних коллекций в EF. Может ли кто-нибудь помочь?
Ответы
Ответ 1
Вы можете загрузить данные и отсортировать их в памяти после загрузки.
IEnumerable<Team> teams = _ctx.Teams
.Include(x => x.TeamMembers)
.Include(x => x.TeamMembers.Select(u => u.User))
.Where(x => x.UserId == ownerUserId)
.OrderBy(x => x.Name).ToList();
foreach (var team in teams)
{
team.TeamMembers = team.TeamMembers.OrderBy(m => m.Name);
foreach (var teamMember in team.TeamMembers)
{
teamMember.Users = teamMember.Users.OrderBy(u => u.Name);
}
}
Или вы можете использовать Projections и использовать функцию "Отслеживание изменений EF" для сортировки вашей коллекции. Вот пример фильтрации Include, но то же самое работает для Ordering.
Ответ 2
Вы можете сбросить команды и членов их команд в анонимный тип (возможно, не то, что вы хотите), например:
public IEnumerable<Team> GetAllTeamsWithMembers(int ownerUserId)
{
return (from t in _ctx.Teams
where t.UserId == ownerUserId
select new {
Team = t,
TeamMembers = t.TeamMembers.OrderBy(m => m.Name)
}).ToList()
}
Затем вы можете пропустить их через:
foreach(Team team in GetAllTeamsWithMembers(1234))
{
string teamName = team.Team.Name;
string firstTeamMemberName = team.TeamMembers.First().Name;
}
Обновление:. Для записи мое мнение заключается в том, чтобы не использовать это решение, но сортировать каждую коллекцию в цикле или во время рендеринга/привязки.
Я удалил второе решение, так как было указано, что EF не может выбрать объекты.