LINQ LEFT JOIN 不适用于 NULL 值

Siv*_*asu 5 c# linq

我有两个表StudentMarks

学生表具有以下字段: StudentID, Name, MarkID(Nullable)标记表具有以下字段: MarkID,Mark

学生桌

StudentID   Name    MarkID

1           Mark    1 

2           Mike    NULL

3           John    NULL

4           Paul    2
Run Code Online (Sandbox Code Playgroud)

标记表

MarkID  Mark

1       80

2       100
Run Code Online (Sandbox Code Playgroud)

如果我使用左连接,那么我只会得到markpaul记录。我想要左表中的所有记录(Student)我的查询是:

   var query = (from s in Students  
               join m in Marks on s.MarkID equals m.MarkID 
               into mar from subMark in mar.DefaultIfEmpty()
               where(m.Mark > 80)
               Select s.Name)
               .ToList() 
Run Code Online (Sandbox Code Playgroud)

注意:这只是一个例子。使用左连接连接两个表并在第二个表上应用 where 条件时,如果第一个表中连接的列值为空,则不会从第一个表中获取记录。

Pan*_*vos 6

NULL 比较总是错误的。这就是 SQL 的三值逻辑的工作方式。如果要匹配值都为空的行,则应使用检查它们是否为空的语句。

在 SQL 语句中,您将编写:

ON S.MARKID=M.MARKID OR (S.MARKID IS NULL AND M.MARKID IS NULL)
Run Code Online (Sandbox Code Playgroud)

在 C# 中,您可以使用比较运算符,您的 LINQ 提供程序会将其转换为IS NULL,例如:

on s.MarkID == m.MarkID || (s.MarkID == null && m.MarkID==null)
Run Code Online (Sandbox Code Playgroud)


Siv*_*asu 5

问题是我们在Left join中使用了where子句,所以它会丢弃空值记录。

var sampleQuery= (from f in food 
            join j in juice on f.ID equals j.ID into juiceDetails from juice in juiceDetails.DefaultIfEmpty()
            where(!j.deleted)
            join fr in fruit on f.ID equals fr.ID into fruitDetails from fruit in fruitDetails.DefaultIfEmpty()
            where(!fr.deleted)
            select new
            {
            // codes

            });
Run Code Online (Sandbox Code Playgroud)

我们必须检查表本身中的 where 子句,而不是这样。像这样

var sampleQuery= (from f in food 
            join j in juice.Table().where(x=>!x.deleted) on f.ID equals j.ID into juiceDetails from juice in juiceDetails.DefaultIfEmpty()              
            join fr in fruit.Table().where(x=>!x.deleted) on f.ID equals fr.ID into fruitDetails from fruit in fruitDetails.DefaultIfEmpty()                
            select new
            {
            // codes

            });
Run Code Online (Sandbox Code Playgroud)

它会正常工作。谢谢你。