2010-05-18 74 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) 
    };