在 LINQ 查询中使用“NOT IN”子句

本文关键字:NOT IN 子句 LINQ 查询 | 更新日期: 2023-09-27 18:33:23

我已经在 LINQPad 中测试了以下 LINQ 查询。但它给了我这个错误:

编译表达式时出错: 编译表达式时出错: 字符串的最佳重载方法匹配。包含(字符串)' 有一些无效的参数 参数"1":无法从"System.Linq.IQueryable"转换为"字符串"

(from t in db.ASN_ITEM
join t0 in db.ASN_MASTER on t.AWB_NO equals t0.AWB_NO
join t1 in db.ITEM_MASTER on t.ITEM_MASTER.ITEM_CODE equals t1.ITEM_CODE
where
  (t.TOT_QTY - t.SCND_QTY) != 0 &&
  !t.AWB_NO.Contains((from t2 in db.ASN_ITEM
                    where
                     t2.SCAN_STAT != 2
                        select new {
                         t2.AWB_NO
                        }).Distinct()) &&
  t.AWB_NO == "E1000001"
select new {
  t.AWB_NO,
  ASN_DATE = t.REC_DATE,
  t.PALLET,
  t.CARTON,
  t.TOT_QTY,
  t.SCND_QTY,
  VAR_QTY = (System.Int32?)(t.SCND_QTY - t.TOT_QTY),
  REMARKS = 
  (t.TOT_QTY - t.SCND_QTY) == 0 ? "No Variance" : 
  (t.TOT_QTY - t.SCND_QTY) > 0 ? "Less Qty" : 
  (t.TOT_QTY - t.SCND_QTY) < 0 &&
  t.TOT_QTY != 0 ? "Excess Qty" : 
  t.TOT_QTY == 0 &&
  t.SCND_QTY != 0 ? "Excess Item" : null,
  t1.PART_NO
}).Distinct()

当我在 where 子句中给出以下条件时,我遇到了这个错误:

!t.AWB_NO.Contains((from t2 in db.ASN_ITEM
                where
                 t2.SCAN_STAT != 2
                    select new {
                     t2.AWB_NO
                    }).Distinct()) 

实际上在SQL查询中,这就是我需要的(如下):

WHERE ASN_ITEM.AWB_NO NOT IN (SELECT DISTINCT AWB_NO FROM ASN_ITEM WHERE SCAN_STAT !=2 )

在 LINQ 查询中使用“NOT IN”子句

你应该反过来做。在子查询上调用Contains(),其中有多个项目的子查询:

!(from t2 in db.ASN_ITEM
  where t2.SCAN_STAT != 2
  select t2.AWB_NO
).Distinct()
 .Contains(t.AWB_NO)

此外,您必须直接选择AWB_NO,如上所示,而不是投影到匿名类型。执行后者将阻止使用 Contains() ,因为集合中的项目类型将与作为 Contains() 参数传递的对象类型不同。

从您的代码中,我发现AWB_NO是一个字符串。如果是这样,那么您在这里做什么:

!t.AWB_NO.Contains((from t2 in db.ASN_ITEM
                where
                 t2.SCAN_STAT != 2
                    select new {
                     t2.AWB_NO
                    }).Distinct()) 

翻译过来就是:"字符串ABW_NO包含(这是这个Contains,而不是这个)一个具有一个字符串属性的匿名类型的不同元素的表,这是不正确的"。这是没有道理的。这不是"不在"查询。您正在检查单个 String 是否包含一组匿名类型对象。

如果你想使用一个String.Contains并检查一个字符串是否包含另一个字符串,那么这将更有意义(可能不是你想要的):

!t.AWB_NO.Contains((from t2 in db.ASN_ITEM
                where
                 t2.SCAN_STAT != 2
                    select t2.AWB_NO).FirstOrDefault()) 

您可能会发现这很有帮助:

如何使用 LINQ 执行"不在"查询?

LINQ to Entities 中的"NOT IN"子句