gpt4 book ai didi

sql - 防止 LINQ to Entity Joins 中的 NULL 检查

转载 作者:行者123 更新时间:2023-12-04 23:02:49 27 4
gpt4 key购买 nike

我们有一个名为 Student 的表。该表有一个名为 Homeroom 的字段,其中的值是学生所在房间的房间号。该值可以为空。

我们有一个名为 Staff 的第二个表。该表还有一个名为 Homeroom 的字段,用于指示教师被分配到哪个类(class)。该值可以为空。

但是当学生的 Homeroom 为 null 时,不应返回 Staff 记录。

我们曾经利用这样一个事实,即在 SQL 中检查两个空字段是否相等总是返回 false。通过 SQL,这就是我们获取我们想要的数据的方式:

SELECT STUDENT.ID, STAFF.NAME as [Homeroom Teacher]
FROM STUDENT
LEFT OUTER JOIN STAFF ON
STAFF.BUILDING = STUDENT.BUILDING AND
STAFF.HOMEROOM = STUDENT.HOMEROOM

学生会回来,但没有老师。

我们将 Entity Framework 与 Code First POCO 对象一起使用。所以,我们有一个 Student 对象和一个 Staff 对象。当我们在 LINQ 中重新创建此 SQL 时:
from student in repo.GetStudents()
join homeroomTeacher in repo.GetStaff()
new { student.Building, Room = student.Homeroom }
equals new { homeroomTeacher.Building, Room = homeroomTeacher.Homeroom }
into roj2
from homeroomTeacherRoj in roj2.DefaultIfEmpty()
select student.Id, homeroomTeacherRoj.Name;

生成的 SQL 包含对两个 Homeroom 字段的 NULL 检查:
SELECT STUDENT.ID, STAFF.NAME
FROM STUDENT AS [Extent1]
LEFT OUTER JOIN [dbo].[STAFF] AS [Extent2] ON
([Extent1].[BUILDING] = [Extent2].[BUILDING]) AND
(
([Extent1].[HOMEROOM] = [Extent2].[HOMEROOM]) OR
(([Extent1].[HOMEROOM] IS NULL) AND ([Extent2].[HOMEROOM] IS NULL))
)

这将返回学生和任何没有定义类(class)的教职员工。根据我们之前编写 SQL 语句的方式,这不是我们想要或期望的。

一个明显的解决方法是确保我们不包括没有家庭房间的员工( join homeroomTeacher in repo.GetStaff().Where(staff => staff.Homeroom != null) 。但是 LINQ 中是否有另一种方法可以防止在加入字段时对字段进行空检查?

最佳答案

如果您将连接移动到 where 子句中,则 DbContext 对象上的以下设置将关闭(引入 EF 6)NULL 检查行为:

Context.Configuration.UseDatabaseNullSemantics = true;

因此,要在 where 子句中“加入”,您可以将查询拆分为 2 个 IQueryable 对象
var subquery = from homeroomTeacher in repo.GetStaff()
where ...
select homeroomTeacher;

var query = from student in repo.GetStudents()
where subquery.Any(homeroomTeacher =>
homeroomTeacher.xxx == student.xxx) -- simplified join for demo code
select student;

仅供引用,引入了 UseDatabaseNullSemantics 来修复此行为,但看起来他们忘记了 JOIN 语义,仅将其应用于 WHERE 语义。

这个原始语句是错误的 - EF 4.3.1 表现出相同的 JOIN 行为:

This essentially means some result sets are now different for EF 6, compared to previous versions. This, in my mind, IS A BIG DEAL !!!! as it introduced bugs into my working solutions !!!!



我在 codeplex 上提出了一个问题: https://entityframework.codeplex.com/workitem/2006

关于sql - 防止 LINQ to Entity Joins 中的 NULL 检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19182319/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com