2017-01-04 81 views
0

我有Join的查詢。這給了我一個內部聯接。我想要完成的是左連接。 我嘗試使用DefaultIfEmpty(),但我無法讓它工作。也許我把它放在查詢的錯誤部分。如何獲得Linq上的左連接

任何人都能指出我出去使用DefaultIfEmpty()的正確方法嗎?

下面是我當前的查詢:

var AppList = (de.ComputerUserApplication) 
        .Where(CUA => CUA.EmployeeID == employeeID) 
        .DefaultIfEmpty() 
        .Join(de.ApplicationTypeMasters, 
         CUA => CUA.RecordType, 
         ATM => ATM.Code, 
         (CUA, ATM) => new ApplicationModel 
         { 
          ApplicationNo = CUA.ApplicationNo, 
          ApplicationCode = CUA.RecordType, 
          ApplicationTypeCode = "", 
          ApplicationName = ATM.Title + " - " + CUA.Description, 
          Status = CUA.Status 
         }); 

另外,我不太確定我是否有正確的查詢。如果你可以,下面是我原來的查詢:

select Cua_ApplicationNo, Cua_Type_Rec, ATM_ApplicationTitle, Cua_Status from ComputerUserApplication 
left join ApplicationTypeMaster 
    on Cua_Type_Rec = ATM_ApplicationCode 
     where Cua_EmployeeID = 'someID' 
+0

@anon把它放在一個新的行沒有任何區別 – Rob

+0

是的。這只是針對我們的內部編碼標準。我需要知道的是如何使用DefaultIfEmpty來實現左外連接。如果你能指出我使用DefaultIfEmpty的方式有什麼問題,那將是非常好的。 – marijanluvlee

+0

我相信'.DefaultIfEmpty'應該放在右邊的桌子上('ApplicationTypeMasters'),而不是放在左邊的桌子上。也就是說,該行應爲:'。加​​入(de.ApplicationTypeMasters.DefaultIfEmpty(),' – Rob

回答

1

您需要使用GroupJoin for an outer join;這將工作假設有0或1個匹配的ApplicationTypeMaster行;如果更多,那麼你需要做一個DefaultIfEmpty然後SelectMany

de.ComputerUserApplication 
    .Where(x => x.EmployeeID == employeeID) 
    .GroupJoin(
     de.ApplicationTypeMasters, 
     CUA => CUA.RecordType, 
     ATM => ATM.Code, 
     (CUA, ATM) => new ApplicationModel 
     { 
      ApplicationNo = CUA.ApplicationNo, 
      ApplicationCode = CUA.RecordType, 
      ApplicationTypeCode = "", 
      ApplicationName = ATM.SingleOrDefault()?.Title + " - " + CUA.Description, 
      Status = CUA.Status 
     } 
); 

如果你不知道有多少匹配的行存在,那麼會的SelectMany給你相同的結果爲SQL:

de.ComputerUserApplication 
    .Where(x => x.EmployeeID == employeeID) 
    .GroupJoin(
     de.ApplicationTypeMasters, 
     CUA => CUA.RecordType, 
     ATM => ATM.Code, 
     (x, y) => new { CUA = x, ATMs = y.DefaultIfEmpty() } 
).SelectMany(x => x.ATMs.Select(ATM => new ApplicationModel 
     { 
     ApplicationNo = x.CUA.ApplicationNo, 
     ApplicationCode = x.CUA.RecordType, 
     ApplicationTypeCode = "", 
     ApplicationName = ATM?.Title + " - " + x.CUA.Description, 
     Status = x.CUA.Status 
     } 
); 

順便說一句,這是爲數不多的幾次我更喜歡查詢語法(SelectMany沒有所有的噪音):

from CUA in de.ComputerUserApplication 
    join x in de.ApplicationTypeMasters on CUA.RecordType equals x.Code into g 
    from ATM in g.DefaultIfEmpty() 
    select new ApplicationModel() 
    { 
    ApplicationNo = CUA.ApplicationNo, 
    ApplicationCode = CUA.RecordType, 
    ApplicationTypeCode = "", 
    ApplicationName = ATM?.Title + " - " + CUA.Description, 
    Status = CUA.Status 
    }; 
+0

我給這個一杆。但是,有沒有你爲什麼喜歡其他的語法具體原因是什麼? – marijanluvlee

+0

這種運作良好。我只需要將SingleOrDefault更改爲FirstOrDefault。 :) – marijanluvlee

+0

@marijanluvlee - 如果您必須使用FirstOrDefault,我認爲這意味着在ApplicationTypeMasters中有> 1匹配的行。在這種情況下,您需要執行DefaultIfEmpty和SelectMany以獲得與SQL相同的結果。我更喜歡查詢語法,因爲它執行SelectMany(這是「正確」的方式),但更清晰。 –

-1

使用DefaultIfEmpty()你可以得到左外連接的結果。並照顧零。

+0

我已經試過了,但我不能完全得到它的權利,也許你可以指出如何使用它。這將是多大讚賞。:) – marijanluvlee

+0

這並沒有真正增加任何信息。OP已經在使用'DefaultIfEmpty'。 – Rob