我们有一个名为 的表Student
。该表有一个名为 的字段Homeroom
,其中的值是学生主室的房间号。该值可以为空。
我们有第二张桌子叫做Staff
. 该表还有一个字段Homeroom
,用于指示教师被分配到哪个教室。该值可以为空。
但是当学生的Homeroom
为空时,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
学生将被退回,但没有老师。
我们正在使用带有 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))
)
这将返回学生,以及没有定义班主任的任何教职员工。根据我们之前编写 SQL 语句的方式,这不是我们想要或期望的。
一个明显的解决方法是确保我们不包括没有教室的员工(join homeroomTeacher in repo.GetStaff().Where(staff => staff.Homeroom != null)
。但是在 LINQ 中是否有另一种方法可以防止在加入他们时对字段进行空检查?