2017-08-18 25 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