【问题标题】:Linq multiple where clause with no or [duplicate]没有或[重复]的Linq多个where子句
【发布时间】:2018-04-11 19:50:17
【问题描述】:

我正在尝试在 linq 中执行多个 where 子句,如下所示:

.Where(x => x.Division == item.Division)
.Where( x => x.ProductID == item.ProductID)
.Where( x => item.supplierNumber == item.supplierNumber)
.Where(x => item.OpcoID == item.OpcoID);

当我吐出 SQL 时,它看起来像这样

WHERE  ( ( [extent1].[Division] = @p__linq__0 ) 
      OR ( ( [extent1].[Division] IS NULL ) 
           AND ( @p__linq__0 IS NULL ) ) ) 
   AND ( ( [extent1].[ProductID] = @p__linq__1 ) 
          OR ( ( [extent1].[ProductID] IS NULL ) 
               AND ( @p__linq__1 IS NULL ) ) ) 
   AND ( ( @p__linq__2 = @p__linq__3 ) 
          OR ( ( @p__linq__2 IS NULL ) 
               AND ( @p__linq__3 IS NULL ) ) ) 
   AND ( ( @p__linq__4 = @p__linq__5 ) 
          OR ( ( @p__linq__4 IS NULL ) 
               AND ( @p__linq__5 IS NULL ) ) ) 

注意

[Extent1].[Division] = @p__linq__0) OR (([Extent1].[Division] IS NULL)

我不希望它包含 或者我只是希望它是

where Division = @p_Linq_0 and [Extent1].[ProductID] = @p_Linq_1 

我做错了什么?

【问题讨论】:

  • 尝试将所有条件组合到一个 where 子句中,并与 && 运算符链接。第三个和第四个,item.supplierNumber == item.supplierNumber 可能是错误的。
  • 尝试将 context.Configuration.UseDatabaseNullSemantics 设置为 true。
  • 仅供参考,最后两个子句将始终为 true 或抛出 NullReferenceException
  • 您没有做错任何事情,LINQ 生成的表达式可以处理所有可能的情况,并且由于 LINQ / C# 当前默认为任何可能为 null 的对象,而 null = null 在SQL 但在 C# 中是正确的,它必须添加额外的测试来处理这种情况。或许当 C# 具有不可为空性时,他们可以改进 LINQ,使其不再进行测试并让用户感到困惑。
  • 正如@RufusL 所说,item.OpcoID == item.OpcoID 也将是微不足道的。

标签: c# linq c#-4.0 entity-framework-6


【解决方案1】:

除非您要比较的值为 null,否则没问题。注意括号:

(
 ([Extent1].[Division] = @p__linq__0) OR
 (([Extent1].[Division] IS NULL) AND (@p__linq__0 IS NULL))
)

基本上,它确保空值在 C# 中进行比较,如果 xy 都是空引用,则 x == y 将评估为 true。在 SQL 中,不会评估为 true,因为 null 值不被视为相等。

LINQ 旨在模拟您编写的 C# 代码,这就是为什么它会像这样检查 null 的原因...但是如果您传入的值不是 null,它不会匹配任何带有 null Division 值的东西.

正如 Evk 所说,如果您使用的是实体框架,则可以在配置中使用 UseDatabaseNullSemantics 属性来避免这种情况:

获取或设置一个值,该值指示在比较两个操作数时是否显示数据库空语义,这两个操作数都可能为空。默认值为假。例如 (operand1 ==operand2) 将被翻译为: (operand1 =operand2) 如果 UseDatabaseNullSemantics 为真,分别为 (((operand1 =operand2) AND (NOT (operand1 IS NULL OR operand2 IS NULL))) OR ((operand1 IS NULL) AND (operand2 IS NULL))) 如果 UseDatabaseNullSemantics 为假。

【讨论】:

    猜你喜欢
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 1970-01-01
    相关资源
    最近更新 更多