Как жаль, что вы не дали нам свои классы и требования вашего запроса, а вместо этого дали нам какое-то SQL-выражение, из которого мы должны угадать ваши классы и отношения между вашими классами.
Мне кажется, что у вас есть таблица Ministries
, где каждый Ministry
имеет как минимум свойства Id
и Name
. У вас также есть таблица MemberGroups
, у каждого MemberGroup
есть Id
, Name
и внешний ключ MemberGroupId
.
Мне кажется, что существует отношение один-ко-многим между Ministries
и MemberGroups
: каждый Ministry
имеет ноль или более MemberGroups
, и каждый MemberGroup
принадлежит ровно одному Ministry
, это министерство, на которое указывает внешний ключ.
Может случиться так, что один ко многим наоборот. или что это отношение один к одному. Вот почему я хотел бы иметь требование. Если все наоборот, ответ будет аналогичным, но вы получите суть.
Если вы следовали первым соглашениям Entity Framework Code , у вас будут такие классы:
class Ministry
{
public int Id {get; set;}
public string Name {get; set;}
// every Ministry has zero or more MemberGroups (one-to-many)
public virtual ICollection<MemberGroup> MemberGroups {get; set;}
}
class MemberGroup
{
public int Id {get; set;}
public string Name {get; set;}
// every MemberGroup belongs to exactly one Ministry, using foreign key
public int MinistryId {get; set;}
public virtual Ministry Ministry {get; set;}
}
public MyDbContext : DbContext
{
public DbSet<Ministry> Ministries {get; set;}
public DbSet<MemberGroup> MemberGroups {get; set;}
}
Это все, что должна знать структура сущностей, чтобы обнаружить ваши таблицы, столбцы и связи между таблицами. Только если вы хотите отклониться от поведения по умолчанию, вам понадобятся атрибуты или свободный API
В структуре сущностей столбцы таблиц представлены не виртуальными свойствами. Виртуальные свойства представляют отношения между таблицами (один ко многим, многие ко многим)
Если вы следовали соглашениям, ваш запрос будет простым и интуитивно понятным:
Требование: дайте мне идентификатор и имя (и, возможно, некоторые другие свойства) всех (или некоторых) министерств, каждое из которых имеет имена (и, возможно, некоторые другие свойства) своих групп пользователей
var result = dbContext.Ministries
.Where(ministry => ...) // only if you don't want all Ministries
.Select(ministry => new
{
// Select only the properties that you plan to use
Id = ministry.Id,
Name = ministry.Name,
...
MemberGroups = ministry.MemberGroups
.Where(memberGroup => ...) // only if you don't want all its MemberGroups
.Select(memberGroup => new
{
// again: only the properties that you plan to use
Id = memberGroup.Id,
Name = memberGroup.Name,
...
// not needed: you know the value
// MinistryId = memberGroup.MinistryId,
})
.ToList(),
});
Платформа сущностей знает ваше отношение «один ко многим» и достаточно умна, чтобы обнаружить, что для этого необходимо (групповое) объединение.
Кстати, если вам нужны только имена членов группы:
...
MemberGroupNames = ministry.MemberGroups
.Select(memberGroup => memberGroup.Name)
.ToList(),
Если вам действительно нравится делать GroupJoin самостоятельно:
var result = dbContext.Ministries.GroupJoin(
dbContext.MemberGroup,
ministry => ministry.Id,
memberGroup => memberGroup.MinistryId,
(ministry, memberGroupsOfThisMinistry) => new
{
Id = ministry.Id,
Name = ministry.Name,
MemberGroups = memberGroupsOfThisMinistry.Select(memberGroup => new
{
Id = memberGroup.Id,
Name = memberGroup.Name,
...
})
.ToList(),
});
И, наконец: если вы не хотите, чтобы министерства с их группами участников были в качестве GroupJoin, а в качестве простого объединения, используйте SelectMany вместо Select или Join вместо GroupJoin:
var result = dbContext.Ministries.SelectMany(ministry.MemberGroups,
(ministry, memberGroup) => new
{
MinistryId = ministry.Id,
MinistryName = ministry.Name,
MemberGroupName = memgerGroup.Name,
});