consulta LINQ con subconsulta como valores separados por comas
Pregunta
En mi solicitud, una empresa puede tener muchos empleados y cada empleado puede tener tiene múltiples direcciones de correo electrónico.
El esquema de base de datos relaciona las tablas de la siguiente manera:
Compañía -> CompanyEmployeeXref -> Empleado -> EmployeeAddressXref -> correo electrónico
Estoy utilizando Entity Framework y quiero crear una consulta LINQ que devuelve el nombre de la empresa y una lista separada por comas de direcciones de correo electrónico que de los empleados. Ésta es la consulta que intento:
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 + ",")
}
Desired Output:
"Company1", "a@company1.com,b@company1.com,c@company1.com"
"Company2", "a@company2.com,b@company2.com,c@company2.com"
...
Sé que este código es incorrecto, creo que me falta por un grupo, pero ilustra el punto. No estoy seguro de la sintaxis. ¿Es esto posible? Gracias por cualquier ayuda.
Solución
Esto es ahora resuelto el problema:
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())
}
)
Otros consejos
En realidad es bastante difícil de hacer esto en el más puro LINQ a SQL (o Marco de la entidad, lo que sea que usted está usando) porque el propio SQL Server no tiene ningún operador agregado que puede producir una lista separada por comas, por lo que no tiene manera de transformar toda esta declaración en una sola consulta. Te podría dar un "single-afirmación" LINQ a SQL respuesta, pero en realidad no va a dar un rendimiento muy bueno, y no estoy seguro de si funcionaría en absoluto en EF.
Es más feo de pero aún mejor si usted acaba de hacer se unen de forma regular, materializar los resultados, a continuación, hacer su concatenación utilizando LINQ a Objetos:
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)
};