2010-05-18 63 views
5

在我的应用程序中,公司可以有许多员工,每个员工可能有多个电子邮件地址。将子查询作为逗号分隔值的Linq查询

数据库架构涉及像这样的表:

公司 - > CompanyEmployeeXref - >员工 - > EmployeeAddressXref - >电子邮件

我使用实体框架和我想创建一个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 + ",") 
      } 
 

Desired Output: 

"Company1", "[email protected],[email protected],[email protected]" 

"Company2", "[email protected],[email protected],[email protected]" 

... 

我知道这个代码是错误的,我想我错过了分组,但是它说明了这一点。我不确定语法。这甚至有可能吗?谢谢你的帮助。

+0

我有一些代码可以做到这一点,但它会为您的案例中的每家公司执行一个新的批处理。我会明天发布,除非有人有更好的建议。 – 2010-05-18 21:18:34

回答

7

这里是我现在解决了这个问题:

 

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

 
+0

你有没有做过这方面的跟踪,看看它使用的是什么SQL? – 2010-05-25 14:55:07

+0

就像一个魅力。谢谢 – 2016-03-18 07:12:48

5

在纯LINQ to SQL(或实体框架,无论使用哪一个)中实现这一点实际上相当困难,因为SQL Server本身没有任何可以生成逗号分隔列表的聚合运算符,所以它具有没有办法将这整个语句转换为单个查询。我可以给你一个“单语句”Linq to 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) 
    };