Linq GroupJoin (join...into) 导致 INNER JOIN?

Posted

技术标签:

【中文标题】Linq GroupJoin (join...into) 导致 INNER JOIN?【英文标题】:Linq GroupJoin (join...into) results in INNER JOIN? 【发布时间】:2018-01-27 14:27:10 【问题描述】:

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

在我的示例中,无论是否有匹配的员工记录,我都需要所有人员记录。

我正在使用以下查询(为了说明而简化):

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(或 join...into)应该可以解决这个问题?我知道我在这里一定犯了一个愚蠢的错误,但我看不到它。

【问题讨论】:

【参考方案1】:

一般来说,查询应该生成left outer join

但请记住,这是 EF,它有来自模型的附加信息。在这种情况下,PersonStaffID 属性看起来是对 Stuff 的强制 FK 约束,因此 EF 知道 Staff 表中始终存在相应的记录,因此忽略您的 left outer join 构造并生成 @改为 987654327@。

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

【讨论】:

就是这样。几年前我也遇到过这个问题,完全忘记了。【参考方案2】:

使用导航属性而不是联接。如果您在 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 : ""
                     ;

【讨论】:

伊万的回答确定了原因。我通常对所有 linq 到实体的东西使用导航属性,但我从中提取的实际案例比发布的示例复杂很多倍,并且我需要使用显式 join...into (GroupJoin) 语法。

以上是关于Linq GroupJoin (join...into) 导致 INNER JOIN?的主要内容,如果未能解决你的问题,请参考以下文章

Linq GroupJoin (join...into) 导致 INNER JOIN?

EFCore 3 GroupJoin下报错

string.Join in Linq to Entity queries

刚学linq 菜鸟教程没看懂 from... in ...where... join ...in ...on...equals...into请大神简单教我下

使用 `groupjoin` 的查询无法翻译,尽管它被记录为受支持

LINQ 常规实践