C# Linq查询转换为SQL会弄乱空参数值

C# Linq查询转换为SQL会弄乱空参数值,c#,sql-server,linq,entity-framework,C#,Sql Server,Linq,Entity Framework,下面是一个简单的LINQ查询: var objs = db.Objects.Where(o => o.Field1 == val); 这转化为SQL查询: select * from [Object] where Field1 = @p1 问题是,val的值也可以合法地为空。SQL不喜欢比较空值;它坚持语法。。。其中字段1为空 除了使用?/isnull操作之外,还有什么方法可以做到这一点呢?这也是LINQ支持中的一个EF弱点。根据val的运行时值,良好的旧LINQ到SQL正确地转换了这

下面是一个简单的LINQ查询:

var objs = db.Objects.Where(o => o.Field1 == val);
这转化为SQL查询:

select * from [Object] where Field1 = @p1
问题是,
val
的值也可以合法地为空。SQL不喜欢比较空值;它坚持语法
。。。其中字段1为空


除了使用
/
isnull
操作之外,还有什么方法可以做到这一点呢?

这也是LINQ支持中的一个EF弱点。根据val的运行时值,良好的旧LINQ到SQL正确地转换了这一点

我建议你这样做:

var objs = db.Objects.Where(
   o => (o.Field1 == val) || (o.Field1 == null && val == null));
如果EF随意转换,SQL Server查询优化器将实际拾取此模式并将其优化为“等于等于空”检查。您甚至可以使用此代码模式来查找索引,它非常有效。在查询计划中,它显示为
IS
,而不是
EQ

如何


这是EF中的一个已知错误。请看@Eranga-谢谢,这似乎值得回答。语法比下面出现的另一个稍微简洁。根据另一个线程,这个问题应该用最新版本的EF解决。你使用的是什么版本?@JeppeStigNielsen-ef5.0。我猜他们没修好…+1谢谢你的提示。我认为
(val==null?o.Field1==null:o.Field1==val)
将编译成更简洁的SQL,不是吗?@Shaul我认为这将编译成一个我不信任优化器的
案例。人们可以查看计划,但我是根据我发布的模式来标准化的。至少在T-SQL中它是最好的。是的,这是EF中一个非常严重的缺陷。IIRC还有一些更糟糕的比特,比如一个空序列的和是空的,而不是0。由于linq的原因,查询看起来像C#,但不幸的是,您不能假设语义是。@ShaulBehr-在我的例子中,它被翻译成:'WHERE(([t0].[Field1]=@p1)或([t0].[Field1]为NULL))'@NicVerAZ这是什么EF版本?他们在最新版本中添加了优化。我没有最近的EF经验,这个答案是3.5年前的。检查你的答案,我想一定是打字错误
o.HasValue
不可能工作。好的,现在可以编译了,但它不能满足我的要求-如果
val
为null,并且
o.Field1
为null,它应该满足条件。@Shaul抱歉等待了很长时间的回复,我在
中测试了
EF5
。其中(o=>o.Field1==null)一切都很好,你在用什么?
EF
顺便说一句,我已经修改了我的answer@Shaul,然后我在EF4.0中进行了测试,一切正常,我使用了MS-SQL2012 Express别担心,问题已经回答了。无论如何,谢谢你的努力。
var objs = db.Objects.Where(o => !o.Field1.HasValue && o.Field1 == val);