VB.Net Linq到实体的空比较-'IsNothing'或'=Nothing'?

VB.Net Linq到实体的空比较-'IsNothing'或'=Nothing'?,vb.net,linq-to-entities,nullable,vb.net-2010,nothing,Vb.net,Linq To Entities,Nullable,Vb.net 2010,Nothing,我们在VB.Net中有几个项目,在许多SQL查询中使用.NETFramework4和LINQtoEntities。对于我们来说,迁移到EF是一个新的转变。我们已经使用了大约4-6个月,并且得到了高层管理层的支持,因为我们可以更快地编写代码。我们仍然使用大量的存储过程,但我们甚至还通过Linq执行这些过程到实体 我希望澄清一些困惑,但我找不到一个有意义的直接答案。我们有一些查询,其中需要特定字段具有空值的记录。这些是简单的select查询、无聚合或左联接等。Microsoft建议查询如下所示: 我

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

我希望澄清一些困惑,但我找不到一个有意义的直接答案。我们有一些查询,其中需要特定字段具有空值的记录。这些是简单的select查询、无聚合或左联接等。Microsoft建议查询如下所示:

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

警告1由于来自equals运算符的null传播,此表达式的计算结果将始终为Nothing。要检查值是否为空,考虑使用“是无”。< /P>
比较这些项目,每个项目都启用option explicit和option strict。如果忽略该警告,我们将获得应用程序运行时要查找的确切记录集。如果我将=符号改为IS,警告就会消失。但为什么这个警告出现在一个项目中而不是其他项目中?即使在MSDN上,也有使用equals运算符的示例,这令人困惑。

我相信您在这里看到的是MyField是一个T类型的null。可能是一个原始整数、单个等

您看到此警告的原因是编译器将基元类型的普通相等运算符提升为NullableOf T版本。它基本上执行以下操作

Dim myField As Integer? = a.MyField
Dim other As Integer? = Nothing
If myField = other Then
 ...
End If
但问题是什么时候是整数?没有任何值,它不会与任何值进行比较。因此,上面的Where子句将始终返回False。编译器试图警告您NullableOf T的这个有问题的角,并将您推到一个is Nothing检查,该检查将确定a.MyField是否具有非null值

这篇博客文章非常详细地解释了为什么会产生这个警告以及它背后的所有机制。本文是为C编写的,但基本前提也适用于VB.Net


生成的列应为Nullablet

因此,您可以检查该字段是否有值,如下所示:

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

至少在LINQ to对象中,您可以使用此选项:

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

这两个值都可以使用,或者两个值都不为空。

VB.NET LINQ还有Equals关键字。我没有办法测试它,但也许可以试试?其中a.MyField等于Nothing@Cory:这是一个上下文关键字,仅用于连接子句AFAIK。我不认为您可以在其他任何地方使用它。因此,如果我理解正确,等号在一个查询中起作用,因为该字段不可为null,但在另一个查询中是一个问题,因为它可为null,因此需要不同的语法。@ChrisJones correct。通常,可以将=与可为空的值一起使用。虽然与Nothing的比较总是返回False,但是编译器会发出一个关于它的警告。如果再处理一点,我可以对数据库中可为null的字符串字段执行Nothing=Nothing,但不能对其他数据类型执行,并且可以使用Is Nothing或Afshin提到的HasValue成员。谢谢你对这个问题的解释。我在几种数据类型上尝试过这个方法,但是在字符串值上就不行了。我能够在可为空的整数、日期和布尔数据类型上使用HasValue成员。
Nullable(Of Integer).Equals(a, b)