如何在实体框架中查询空值?

Adr*_*scu 107 .net ado.net entity-framework

我想执行这样的查询

   var result = from entry in table
                     where entry.something == null
                     select entry;
Run Code Online (Sandbox Code Playgroud)

并得到一个IS NULL生成.

编辑:在前两个答案后,我觉得有必要澄清我正在使用实体框架而不是Linq to SQL.object.Equals()方法似乎不适用于EF.

编辑2:上述查询按预期工作.它正确生成IS NULL.然而,我的生产代码是

value = null;
var result = from entry in table
                         where entry.something == value
                         select entry;
Run Code Online (Sandbox Code Playgroud)

并且生成的SQL是something = @p; @p = NULL.似乎EF正确地转换了常量表达式,但是如果涉及变量,它就像正常比较一样处理它.实际上是有道理的.我会结束这个问题

Blu*_*eft 125

Linq-to-SQL的解决方法:

var result = from entry in table
             where entry.something.Equals(value)
             select entry;
Run Code Online (Sandbox Code Playgroud)

Linq-to-Entities的解决方法(哎哟!):

var result = from entry in table
             where (value == null ? entry.something == null : entry.something == value)
             select entry;
Run Code Online (Sandbox Code Playgroud)

这是一个令人讨厌的虫子,几次咬我. 如果此错误也影响了您,请访问UserVoice上错误报告,并让Microsoft知道此错误也会影响您.


编辑: 此错误正在EF 4.5中修复!感谢大家提出这个错误!

为了向后兼容,它将选择加入 - 您需要手动启用设置才能entry == value工作.还没有关于这个设置是什么的消息.敬请关注!


编辑2: 根据EF团队的这篇文章,这个问题已经在EF6中得到修复!哇噢!

我们更改了EF6的默认行为以补偿三值逻辑.

这意味着依赖于旧行为的现有代码(null != null但仅在与变量进行比较时)将需要更改为不依赖于该行为,或者设置UseCSharpNullComparisonBehavior为false以使用旧的行为.

  • 我已经投了臭虫报告.希望他们解决这个问题.我不能说我真的记得vs2010测试版中存在这个bug ... (6认同)
  • @ leen3o(或其他任何人) - 有没有人发现这个涉嫌修复的地方在EF 4.5/5.0中?我正在使用5.0,它仍然行为不端. (5认同)
  • Object.Equals实际上是`(其中Object.Equals(entry.something,value))` (4认同)
  • 哦来微软......真的吗?!?!?在4.1版本中?!?!+1 (2认同)

ITm*_*eze 17

从Entity Framework 5.0开始,您可以使用以下代码来解决您的问题:

public abstract class YourContext : DbContext
{
  public YourContext()
  {
    (this as IObjectContextAdapter).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = true;
  }
}
Run Code Online (Sandbox Code Playgroud)

这应该可以解决您的问题,因为实体Framerwork将使用'C#like'null比较.


div*_*ega 16

LINQ to Entities有一个稍微简单的解决方法:

var result = from entry in table
         where entry.something == value || (value == null && entry.something == null)
         select entry;
Run Code Online (Sandbox Code Playgroud)

这是有用的,因为AZ注意到,LINQ to Entities特殊情况x == null(即与null常量的相等比较)并将其转换为x IS NULL.

我们正在考虑改变这种行为,以便在等式的两边都可以为空的情况下自动引入补偿比较.但是有几个挑战:

  1. 这可能会破坏已经依赖于现有行为的代码.
  2. 即使很少使用null参数,新转换也可能影响现有查询的性能.

无论如何,我们是否开始研究这将取决于客户分配给它的相对优先级.如果您关心这个问题,我建议您在我们的新功能建议网站上投票:https://data.uservoice.com.


Svi*_*ish 8

如果它是可空类型,也许尝试使用HasValue属性?

var result = from entry in table
                 where !entry.something.HasValue
                 select entry;
Run Code Online (Sandbox Code Playgroud)

没有任何EF在这里测试虽然...只是一个建议=)


Kon*_*kus 5

var result = from entry in table
             where entry.something.Equals(null)
             select entry;
Run Code Online (Sandbox Code Playgroud)

MSDN参考:LINQ to SQL:关系数据的.NET语言集成查询


Osc*_*ero 5

处理Null Comparisons Object.Equals()而不是使用==

检查此参考