2017-08-18 26 views
1

我引用接受這個問題的答案: LINQ to SQL multiple tables left outer joinLinq Group加入(加入...)INNER JOIN的結果?

在我的例子,我需要所有的人記錄,而不管是否有匹配的員工記錄。

我使用下面的查詢(簡化illustation的緣故):

var result = from person in context.Person 
        join staffQ in context.Staff 
         on person.StaffID equals staffQ.ID into staffStaffIDGroup 
        from staff in staffStaffIDGroup.DefaultIfEmpty() 
        select new PersonModel() 
        { 
         ID = person.ID, 
         Fname = person.Fname, 
         Lname = person.Lname, 
         Sex = person.Sex, 
         Username = staff != null ? staff.Username : "" 
        }; 

然而,出乎我的意料,查詢結果在下面的SQL與內部連接,從而消除了我需要的記錄結果集。

SELECT 
[Extent1].[ID] AS [ID], 
[Extent1].[fname] AS [fname], 
[Extent1].[lname] AS [lname], 
[Extent1].[sex] AS [sex], 
[Extent2].[username] AS [username] 
FROM [dbo].[Person] AS [Extent1] 
INNER JOIN [dbo].[Staff] AS [Extent2] ON [Extent1].[StaffID] = [Extent2].[ID] 

我以爲GroupJoin(或加入...到)應該繞過這個?我知道我一定在這裏犯了一個愚蠢的錯誤,但我看不到它。

回答

2

一般查詢應產生left outer join

但請記住,這是EF,它有來自模型的附加信息。在這種情況下,看起來PersonStaffID屬性是強制FK約束爲Stuff,因此EF知道Staff表中始終存在對應的記錄,因此忽略了您的left outer join構造並生成inner join。同樣,模型(屬性,不管它們是否需要,關係 - 是否需要等)都允許EF執行類似的智能決策和優化。

+1

就是這樣。幾年前我也碰到過這個,並且完全忘了。 – esmoore68

0

使用導航屬性而不是加入。如果你在EF LINQ中使用Join,你幾乎總是在做錯誤的事情。

喜歡的東西

var result = from person in context.Person 
        select new PersonModel() 
        { 
         ID = person.ID, 
         Fname = person.Fname, 
         Lname = person.Lname, 
         Sex = person.Sex, 
         Username = person.StaffId != null ? Person.Staff.Username : "" 
        }; 
+0

伊萬的答案釘住了原因。我通常對所有linq實體的東西都使用導航屬性,但是我提取的實際案例比發佈的示例複雜得多,我需要使用顯式連接...(GroupJoin)語法。 – esmoore68