2017-02-23 50 views
1

我才意识到,当我要求这个为什么LINQ的子串()忽略空值

Orders.Where(y => y.Sub_Item_Id.Substring(0, 10) != y.Sub_Item_Site_Id.Substring(0, 10)) 

查询忽略可能在y.Sub_Item_Site_Id存在我所有的空值。所以当我在Sub_Item_Id中有一个值并且在Sub_Item_Site_Id中为null时,查询并不认为这是!=

为什么?


我还测试了相同的查询与SQL

select 
    * 
from 
    orders as o 
where 
    LEFT(o.sub_item_id, 10) <> LEFT(o.sub_item_site_id, 10) 

我也得到了相同的结果。我有我所有不同的值,但不是当我在o.sub_item_id中有值,在o.sub_item_site_id中为null时。

您能否解释SQL和Linq如何以及为何如此工作。

回答

1

Substring()忽略空,在你的查询,如果其中一个字符串将是空的,你会得到NullPointerException,如果该字符串的一个短于10个符号,你会得到ArgumentOutOfRangeException

https://msdn.microsoft.com/library/aka44szs(v=vs.110).aspx

检查您的数据和您的查询。

+0

不好意思,但是如果系统产生异常并且这些异常由系统本身处理,结果是系统忽略了一些东西。好的,好的。因此,Linq查询会忽略这些行,因为您认为系统会生成异常。那么SQL查询呢?同样,LEFT()生成异常? –

0

涉及NULL的关系表达式实际上会再次产生NULL。为了过滤空值,您需要使用IS NULLIS NOT NULL。你可以找到一个答案here

0

您可能需要添加一个标签,指出您的LinQ在后台连接到数据库以在那里执行SQL。没有这些信息,Maksim是正确的。在普通的Linq-to-Objects C#中,你会得到适当的例外。

但是,当你的LinQ被翻译并作为SQL执行时,你刚刚遇到了一个令人惊讶的不直观的SQL特性:NULL从来不是等于其他任何东西。甚至不是NULL。而且从不是不等于其他任何东西。没有一个值或另一个NULL。它只是从来没有产生比较真实,无论你比较它。

您可以使用IS语法来询问是否为 NULL。或者,在执行语句之前,您可以用默认值替换NULL。但是比较现有的值和NULL总是会产生false,因为NULL不等于任何东西,甚至不是NULL本身。