7

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

我希望消除一些困惑,但我找不到一个有意义的直接答案。我们有一些查询,我们想要特定字段具有 NULL 值的记录。这些是简单的选择查询,没有聚合或左连接等。微软建议查询看起来像这个MSDN 链接

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

我有几个项目正是这样做的,而且效果很好,IDE 中没有警告。最近,另一个开发人员创建了一个新项目,当他像上面那样进行 null 检查时,我们都会在 IDE 中收到以下警告:

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

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

4

3 回答 3

6

生成的列应该是Nullable(Of T)

因此,您可以像这样检查该字段是否具有值:

dim query = from a in MyContext.MyTables
Where Not a.MyField.HasValue
Select a
于 2012-07-10T19:24:06.717 回答
2

我相信你在这里看到的MyField是一种Nullable(Of T)类型。可能是原始Integer的 ,Single等...

您看到此警告的原因是编译器将原始类型的正常相等运算符提升到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。

于 2012-07-10T18:52:23.407 回答
0

至少在 LINQ to 对象中,您可以改用它:

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

这适用于两者,或者两个值都不是 Nothing。

于 2017-10-11T13:31:52.367 回答