可空对象必须具有值 - 为什么?

5
我有以下的LINQ查询:
from p in dc.Purchases
where invoiceNumber == null || p.InvNumber == invoiceNumber.Value
select p;

"invoiceNumber"是一个可空的整数类型,当它为空时,程序会抛出“可空对象必须具有值”的错误。为什么程序已经明确检查了它是否为空,还会出现这种情况呢?有没有任何解决方法?
谢谢。

3
当您将空值检查更改为 invoiceNumber.HasValue 时,是否会有任何区别? - Daniel Hilgarth
你使用的是哪个 Linq 提供程序?Linq to SQL、Entity Framework、Linq to Objects ... ? - AakashM
LINQ to SQL。使用 HasValue 时没有区别。 - Chris
1
如果将“p.InvNumber == invoiceNumber.Value”替换为“p.InvNumber == invoiceNumber”,会发生什么? - cookieMonster
请查看关于LINQ中可空类型的问题:https://dev59.com/j1fUa4cB1Zd3GeqPMOTB - cookieMonster
显示剩余2条评论
9个回答

2

我认为您的查询存在问题。根据您提供的代码,我认为invoiceNumber是一个本地变量或参数。如果是这样,那么为什么在查询中检查invoiceNumber == null呢?应该将此类检查与查询分开执行:

if(invoiceNumber == null)
{
    return dc.Purchases; 
    // the query would evaluate to this because invoiceNumber == null will allways return true.
}
else
{
    return 
        from p in dc.Purchases 
        where p.InvNumber == invoiceNumber.Value
        select p;
}

0

问题可能出在 Linq-to-Sql 上 - 它试图将 where 语句转换为 SQL,因此即使 invoiceNumber.Value 为空也可以调用它。

请尝试使用 invoiceNumber == null || p.InvNumber == invoiceNumber 的 where 子句。

希望能有所帮助。


0

试试这个:

from p in dc.Purchases
where invoiceNumber == null ||(invoiceNumber!=null && p.InvNumber == invoiceNumber.Value)
select p;

2
不合理 - || 运算符只有在第一个参数为 false 时才会评估第二个参数。 - Ventsyslav Raikov
不是在LINQ-to-SQL中。查询被翻译为SQL并且表达式的所有术语都被评估。没有像C#中那样的短路。使用null-coalescing运算符??(类似于ISNULL)或使用正常的SQL null行为,当值为null时计算结果为false:where p.InvNumber == invoiceNumber。或者,在invoiceNumber不为null时添加一个单独的.Where()条件。 - Suncat2000

0

检查这个

from p in dc.Purchases
where (invoiceNumber == null ? p.InvNumber == null : p.InvNumber == invoiceNumber.Value)
select p;

0

关于什么

from p in dc.Purchases 
where (invoiceNumber ?? p.InvNumber) == p.InvNumber
select p;

但是,我想问一下,如果invoiceNumbernull,为什么要运行这个语句呢?


如果它是空的,它应该检索所有内容。 - Chris
@Chris,因此,对于你的数据库来说,另一个没有where子句的语句会更有效率。 - Jodrell

0
使用 HasValue 属性来检查 Nullable 是否有值。
from p in dc.Purchases
where !invoiceNumber.HasValue || p.InvNumber == invoiceNumber.Value
select p;

0

你没有说,但我怀疑 p.InvNumber 也是可空的。如果是这样,请不要使用 .Value

from p in dc.Purchases
where invoiceNumber == null || p.InvNumber == invoiceNumber
select p;

0

你不需要明确地检查 null。可空值有两种情况,可能为 null 或具有某个值。

例如:

情况1-

 int ? invoiceNumber = null;
 var prods = from p in dc.Purchases 
             where p.InvNumber == invoiceNumber
             select p;

情况2-

 int ? invoiceNumber = 100;
 var prods = from p in dc.Purchases 
             where p.InvNumber == invoiceNumber
             select p;

相同的linq语句将在两种情况下都起作用。


为什么第一个案例有where子句? - Jodrell
我只想表达相同的linq查询将在两种情况下工作。无论invoiceNumber是否为null或具有某些值。 - userGS

0

nullable类型的基本概念是...底层类型将具有其范围中指定的所有值+一个null值,以增加与数据库编程的灵活性。

nullable类型有两个只读属性 1)HasValue 2)Value

HasValueboolean类型,如果Value中有一些值,则会自动设置为true。 因此,在比较时,您必须先使用HasValue,然后使用Value。如果直接使用Value,并且它为null,则会抛出上述异常。

记住这些,我也对这个片段表示怀疑,其中invoiceNumber == null 你应该尝试invoiceNumber.Value==null(而不是invoiceNumber)

或者

where invoiceNumber.HasValue && p.InvNumber == invoiceNumber.Value 

谢谢


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接