VB.Net Linq到实体空比较 - '什么都不是'或'=什么都没有'?

时间:2012-07-10 18:46:10

标签: vb.net linq-to-entities nullable vb.net-2010 nothing

我们在VB.Net中有几个项目,使用.Net Framework 4和Linq to Entities来处理我们的许多SQL查询。迁移到EF对我们来说是一个新的转变(已经使用了大约4-6个月),并得到了高层管理人员的支持,因为我们可以更快地编写代码。我们仍然使用很多存储过程,但我们甚至也通过Linq到实体执行这些过程。

我希望能够清除一些混乱,我找不到直接的答案。我们有一些查询,我们想要特定字段具有NULL值的记录。这些是简单的选择查询,没有聚合或左连接等.Microsoft建议查询看起来像这样MSDN Link

dim query = from a in MyContext.MyTables
Where a.MyField = Nothing
Select a

我有几个项目,我这样做,它工作得很好,在IDE中没有警告。最近,另一个开发人员创建了一个新项目,当他像上面那样进行空检查时,我们都在IDE中收到了这个警告:

警告1此表达式将始终求值为Nothing(由于来自equals运算符的null传播)。要检查值是否为null,请考虑使用“Is Nothing”。

比较项目时,每个项目都有选项显式和选项严格。如果我们忽略警告,我们会在应用程序运行时获得我们正在寻找的确切记录集。如果我将=符号更改为IS,则警告消失。但为什么这个警告出现在一个项目而不是其他项目?即使在MSDN上也有使用equals运算符的例子,这很令人困惑。

3 个答案:

答案 0 :(得分:5)

生成的列应为Nullable(Of T)

所以你可以检查那个字段是否有价值:

dim query = from a in MyContext.MyTables
Where Not a.MyField.HasValue
Select a

答案 1 :(得分:2)

我相信您在这里看到的是MyFieldNullable(Of T)类型。可能是原始IntegerSingle等......

您看到此警告的原因是因为编译器将基元类型的常规相等运算符提升为Nullable(Of T)版本。它基本上执行以下

Dim myField As Integer? = a.MyField
Dim other As Integer? = Nothing
If myField = other Then
 ...
End If

但问题是当Integer?的值为Nothing时,它不会与任何内容进行比较。因此,上述Where子句将始终返回False。编译器正试图警告您Nullable(Of T)这个有问题的角落并推送您进行Is Nothing检查,这将确定a.MyField是否具有非空值。

这篇博客文章详细解释了为什么要生成此警告以及其背后的所有机制。本文是为C#编写的,但基本前提也适用于VB.Net。

答案 2 :(得分:0)

至少在LINQ to对象中你可以使用它:

Nullable(Of Integer).Equals(a, b)

这两种值都可以正常工作,或者两者都不是Nothing。