Linq GroupJoin(加入......)会导致INNER JOIN?

时间:2017-08-18 20:17:42

标签: entity-framework linq

我引用了这个问题的接受答案: LINQ to SQL multiple tables left outer join

在我的示例中,无论是否存在匹配的Staff记录,我都需要所有Person记录。

我使用以下查询(为了插图而简化):

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 : ""
                     };

但是,与我的期望相反,查询会产生以下带有INNER JOIN的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 个答案:

答案 0 :(得分:2)

通常,查询应生成left outer join

但请记住,这是EF,它还有来自模型的其他信息。在这种情况下,StaffID的{​​{1}}属性看起来是对Person强制执行的FK约束,因此EF知道Stuff表中始终存在相应的记录,因此忽略您的Staff构造并生成left outer join

同样,模型(属性,无论它们是否需要,关系 - 是否需要等)允许EF执行类似的智能判决和优化。

答案 1 :(得分:0)

使用导航属性而不是加入。如果你正在使用加入EF LINQ,你几乎总是做错了。

这样的东西
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 : ""
                     };