LINQ запрос с подзапросным примерным значениями, разделенными запятыми значениями
Вопрос
В моем заявлении компания может иметь много сотрудников, и каждый сотрудник может иметь несколько адресов электронной почты.
Схема базы данных связывает такие таблицы:
Компания -> CompanyMobleeExref -> Сотрудник -> Сотрудник -> WatereeAddressxref -> Email
Я использую Framework Entity, и я хочу создать запрос LINQ, который возвращает имя компании и список, разделенный запятыми со списком адресов электронной почты сотрудника. Вот запрос, который я пытаюсь:
from c in Company
join ex in CompanyEmployeeXref on c.Id equals ex.CompanyId
join e in Employee on ex.EmployeeId equals e.Id
join ax in EmployeeAddressXref on e.Id equals ax.EmployeeId
join a in Address on ax.AddressId equals a.Id
select new {
c.Name,
a.Email.Aggregate(x=>x + ",")
}
Желаемый выход: «Company1», «A @ Company1.com, B @ Company1.com, C @ Company1.com» «Company2», «A @ Company2.com, B @ Company2.com, C @ Company2.com». Находятся
Я знаю, что этот код не прав, я думаю, что я скучаю по группе, но это иллюстрирует точку. Я не уверен в синтаксисе. Это даже возможно? Спасибо за любую помощь.
Решение
Вот сейчас я решил проблему:
from c in Company
join ex in CompanyEmployeeXref on c.Id equals ex.CompanyId
join e in Employee on ex.EmployeeId equals e.Id
join ax in EmployeeAddressXref on e.Id equals ax.EmployeeId
join a in Address on ax.AddressId equals a.Id
group a.Email by new {c.Name} into g
select new {
Company=g.Key.Name,
Email=g.Select(e=>e).Distinct()
}
).ToList()
.Select(l=>
new {
l.Name,
Email=string.Join(",", l.Email.ToArray())
}
)
Другие советы
На самом деле довольно сложно сделать это в Pure LINQ к SQL (или основой Framework, в зависимости от того, что вам не использует), поскольку сам SQL Server не имеет никакого совокупного оператора, который может создать список разделить запятую, поэтому у него нет способа преобразовать Все это утверждение в единственном запросе. Я мог бы дать вам «однотверждение» Linq для SQL-ответа, но на самом деле не собирается дать вам очень хорошую производительность, и я не уверен, что будет работать вообще в EF.
Это уродливее, но все же лучше, если вы просто делаете регулярный присоединение, материализуйте результаты, затем выполните ваше конконтрацию с помощью Linq к объектам:
var rows =
(from c in Company
join ex in CompanyEmployeeXref on c.Id equals ex.CompanyId
join e in Employee on ex.EmployeeId equals e.Id
join ax in EmployeeAddressXref on e.Id equals ax.EmployeeId
join a in Address on ax.AddressId equals a.Id
select new
{
c.Name,
a.Email
}).AsEnumerable();
var emails =
from r in rows
group r by r.Name into g
select new
{
Name = g.Key,
Emails = g.Aggregate((x, y) => x + "," + y)
};