2011-10-05 76 views
61

我試圖在LINQ中實現一個查詢,該查詢在ON子句中使用了具有多個條件的左外連接。LINQ加入條件中的多個條件

我將使用下面兩個表項目(專案編號,項目名)和任務(的TaskID,專案編號,TASKNAME,已完成)的例子。我想查看所有項目的完整列表及其各自的任務,但只列出已完成的任務。

我無法使用Completed == true的過濾器,因爲這將過濾掉沒有完成任務的任何項目。相反,我想將Completed == true添加到連接的ON子句中,以便顯示完整的項目列表,但只顯示完成的任務。沒有完成任務的項目將顯示Task的空值爲單行。

這是查詢的基礎。

from t1 in Projects 
join t2 in Tasks 
on new { t1.ProjectID} equals new { t2.ProjectID } into j1 
from j2 in j1.DefaultIfEmpty() 
select new { t1.ProjectName, t2.TaskName } 

如何將&& t2.Completed == true添加到on子句中?

我似乎無法找到任何關於如何做到這一點的LINQ文檔。

回答

82

你只需要命名的匿名性質兩側

on new { t1.ProjectID, SecondProperty = true } equals 
    new { t2.ProjectID, SecondProperty = t2.Completed } into j1 

基於@svick的意見是相同的,這裏要說的是可能會更有意義另一種實現方式:

from t1 in Projects 
from t2 in Tasks.Where(x => t1.ProjectID == x.ProjectID && x.Completed == true) 
       .DefaultIfEmpty() 
select new { t1.ProjectName, t2.TaskName } 
+0

這似乎是一個非顯而易見的方式來做到這一點。我不確定我會理解它想要做什麼。 – svick

+1

@svick - 使用匿名類型允許您加入多個條件。您只需確保兩種類型的屬性名稱都匹配。不確定混淆來自哪裏? – Aducci

+0

令人困惑的是,它確實更有意義,因爲用'和'加入了兩個平等點,而不是某個「怪異」對象的一個​​平等點。爲了證明我的觀點,你的代碼是錯誤的。對於它的工作,你必須在左邊有'true',在右邊有't2.Complete'。 – svick

2

你不能這樣做。 join子句(和Join()擴展方法)僅支持等寬線。這也是它爲什麼使用equals而不是==的原因。即使你可以做這樣的事情,它也行不通,因爲join是一個內連接,而不是外連接。

20

在這裏你去:

from b in _dbContext.Burden 
join bl in _dbContext.BurdenLookups on 
new { Organization_Type = b.Organization_Type_ID, Cost_Type = b.Cost_Type_ID } equals 
new { Organization_Type = bl.Organization_Type_ID, Cost_Type = bl.Cost_Type_ID }