Linq query with subquery as comma-separated values

妖精的绣舞 提交于 2019-11-30 04:58:22

问题


In my application, a company can have many employees and each employee may have have multiple email addresses.

The database schema relates the tables like this:

Company -> CompanyEmployeeXref -> Employee -> EmployeeAddressXref -> Email

I am using Entity Framework and I want to create a LINQ query that returns the name of the company and a comma-separated list of it's employee's email addresses. Here is the query I am attempting:


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"

...

I know this code is wrong, I think I'm missing a group by, but it illustrates the point. I'm not sure of the syntax. Is this even possible? Thanks for any help.


回答1:


Here's now I solved the problem:


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())
                }
        )





回答2:


It's actually rather difficult to do this in pure Linq to SQL (or Entity Framework, whichever one you're using) because SQL Server itself doesn't have any aggregate operator that can produce a comma delimited list, so it has no way to transform this entire statement into a single query. I could give you a "single-statement" Linq to SQL answer but it's actually not going to give you very good performance, and I'm not sure if it would work at all in EF.

It's uglier but still better if you just do a regular join, materialize the results, then do your concatenation using Linq to Objects:

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)
    };


来源:https://stackoverflow.com/questions/2861202/linq-query-with-subquery-as-comma-separated-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!