【问题标题】:How express SQL left join with IS NULL in LINQ如何在 LINQ 中使用 IS NULL 表达 SQL 左连接
【发布时间】:2021-04-30 05:14:06
【问题描述】:

我正在尝试编写与以下 SQL 等效的 LINQ:

SELECT i.ItemID, i.ItemName 
FROM Items AS i 
LEFT JOIN BillOfMaterials AS bom ON bom.ItemID = i.ItemID
WHERE bom.ItemID IS NULL

这将返回itemid 未出现在BillofMaterials.ItemID 列中的一组项目。

我尝试了以下方法(并不奇怪):

from i in ctx.Items 
join b in ctx.BillOfMaterials on i.ItemID equals b.ItemID
into joinedTable
from j in joinedTable.DefaultIfEmpty().Where(w => w.ItemID == null)
select new
{
    i.ItemID,
    i.ItemName
};

【问题讨论】:

  • 定义“不起作用”。您是否收到编译错误、运行时异常和/或不正确的结果?

标签: asp.net linq


【解决方案1】:

由于您似乎对实际的 BOM 对象不感兴趣,只要它们存在与否,我建议使用仅包含存在检查的表达式:

from i in ctx.Items 
where !ctx.BillOfMaterials.Any(b => i.ItemID == b.ItemID)
select new
{
    i.ItemID,
    i.ItemName
};

它更短,并且更好地描述了您正在检查的内容。同样取决于 EF 的智能程度(或不智能),它甚至可能更高效,因为 BillOfMaterials 数据永远不会作为 BillOfMaterial 对象加载到 .NET 内存中。

【讨论】:

  • 你说得对,我对 BOM 记录本身不感兴趣 - 为简洁起见接受了答案,谢谢
【解决方案2】:

sql 中的WHERE bom.ItemID IS NULL 对应于 Linq 中的 j == null
Where(w => w.ItemID == null) 在这里不起作用,因为 wnull 并引发了异常。
left join Linq 的正确语法如下:

from i in ctx.Items 
join b in ctx.BillOfMaterials on i.ItemID equals b.ItemID into joinedTable
from j in joinedTable.DefaultIfEmpty()
where j == null
select new
{
    i.ItemID,
    i.ItemName
};

希望对您有所帮助。

【讨论】:

  • 谢谢 Sajid,您的第一个建议产生了正确的结果。第二个不会编译“表达式树 lambda 可能不包含空传播运算符”
猜你喜欢
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多