我们今天在这行代码中遇到Nullable object must have a value
错误:
list = From x In Me Where x.FooDate.HasValue AndAlso x.FooDate.Value.Date >= barDate
有趣的是,我确信这曾经很好地工作(并且在底层数据中总是存在一些空值)。从逻辑上讲,它看起来很好。检查HasValue
和AndAlso
看起来,好像它们会保护我们免受任何空危险。
但突然间他们似乎没有。我错过了什么吗?
好的,我们可以纠正它,这消除了错误:
list = From x In Me Where If(x.FooDate.HasValue, x.FooDate.Value.Date >= barDate,False)
但这对我来说不太可读。有什么想法吗?
更新......和忏悔:
在简化上面的代码来缩短行时,我遗漏了一小部分代码。最初的问题应该是这样的:
list = From x In Me Where x.FooDate.HasValue AndAlso x.FooDate.Value.Date >= fromDate And x.FooDate.Value.Date <= toDate
由于短路和运算符优先级的规则(对于我自己的很久以前的问题,outlined in an answer)我需要在指令的第二部分附加括号,以便停止LINQ评估第二部分{{ 1}}:
x.FooDate.Value.Date
感谢两个答案,即抛出快速测试代码以验证LINQ是否真的服从AndAlso并迫使我更仔细地查看原始问题。
答案 0 :(得分:1)
我非常确定您的查询是安全的,至少遵循以下示例代码:
Dim dateList As New List(Of Nullable(Of Date))
For i As Int32 = 0 To 12
If (i Mod 3 = 0) Then
dateList.Add(Nothing)
Else
dateList.Add(New Date(2012, i, 1))
End If
Next
Dim july = New Date(2012, 7, 1)
Dim fromJuly = (From m In dateList
Where m.HasValue AndAlso m.Value.Date >= july).ToList
注意:如果我用AndAlso
替换And
,我会得到您的例外。
所以问题必定在其他地方。请告诉我们你的课程。
答案 1 :(得分:1)
它应该工作。我写了这段代码,即使将barDate
设置为Nothing
,它也能很好用。
Sub Main()
Dim barDate As Nullable(Of DateTime) = Nothing
Dim List = From x In GetDates() Where x.FooDate.HasValue AndAlso x.FooDate.Value.Date > barDate
Console.WriteLine(List.Count())
End Sub
Function GetDates() As List(Of Foo)
Dim l = New List(Of Foo)
l.Add(New Foo With {.FooDate = DateTime.Now})
l.Add(New Foo)
Return l
End Function
Class Foo
Private m_fooDate As DateTime?
Public Property FooDate() As DateTime?
Get
Return m_fooDate
End Get
Set(ByVal value As DateTime?)
m_fooDate = value
End Set
End Property
End Class