VB.Net Linq to Entities Null 比较 - “啥都没有”或“= 啥都没有”?

Posted

技术标签:

【中文标题】VB.Net Linq to Entities Null 比较 - “啥都没有”或“= 啥都没有”?【英文标题】:VB.Net Linq to Entities Null Comparison - 'Is Nothing' or '= Nothing'?VB.Net Linq to Entities Null 比较 - “什么都没有”或“= 什么都没有”? 【发布时间】:2012-07-10 07:34:49 【问题描述】:

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

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

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

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

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

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

【问题讨论】:

VB.NET LINQ 也有 Equals 关键字。我没有办法测试它,但也许可以试试? Where a.MyField Equals Nothing @Cory:这是一个上下文关键字,仅在 Join 子句 (AFAIK) 中使用。我认为你不能在其他任何地方使用它。 【参考方案1】:

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

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

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

【讨论】:

我对几种数据类型进行了尝试,但它不适用于字符串值。我能够在可为空的整数、日期和布尔数据类型上使用 HasValue 成员。【参考方案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。

http://blogs.msdn.com/b/abhinaba/archive/2005/12/14/503533.aspx

【讨论】:

所以如果我理解这一点,等号在一个查询中有效,因为该字段不可为空,但在另一个查询中是一个问题,因为它可以为空,因此需要不同的语法。 @ChrisJones 正确。通常您可以将= 与可为空的值一起使用。虽然与Nothing 的比较总是会返回False,但编译器会发出警告 再玩一点,我可以对数据库中可以为空的字段执行 = Nothing,但不能使用其他数据类型,并且可以使用 Is Nothing 或 Afshin 提到的 HasValue 成员。感谢您对此有所了解。【参考方案3】:

至少在 LINQ to 对象中,您可以使用它来代替:

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

这对两者都适用,两个值中的一个或都不是 Nothing。

【讨论】:

以上是关于VB.Net Linq to Entities Null 比较 - “啥都没有”或“= 啥都没有”?的主要内容,如果未能解决你的问题,请参考以下文章

Linq to Entities 日期部分优化

为啥 LINQ-to-Entities 将此查询放在子选择中?

Linq-to-Entities:带有 WHERE 子句和投影的 LEFT OUTER JOIN

如果存在-UPDATE-else-INSERT 与 Linq-to-Entities?

LINQ to Entities 选择新建

在 LINQ to Entities 中批量删除