当我进入Read循环时,我得到一个索引越界错误。我认为这取决于读者的序数价值,但我不确定为什么我会得到它。
Private Function Create(Reader As SqlDataReader) As IEnumerable(Of MyObject)
SetOrdinals(MyObjectReader)
Dim MyObjects = New List(Of MyObject)
While MyObjectReader.Read()
Dim Temp = New MyObject() With {
.FirstValue = MyObjectReader.GetValue(Of Integer)(MyObjectReader(FirstValue_Ord)),
.SecondValue = If(MyObjectReader.GetValue(Of String)(MyObjectReader(SecondValue_Ord)), String.Empty).Trim(),
.ThirdValue = If(MyObjectReader.GetValue(Of String)(MyObjectReader(ThirdValue_Ord)), String.Empty).Trim(),
MyObjects.Add(Temp)
End While
Return MyObjects
End Function
Private Sub SetOrdinals(MyObjectReader As SqlDataReader)
FirstValueOrd = MyObjectReader.GetOrdinal("FirstValue")
SecondValue_Ord = MyObjectReader.GetOrdinal("SecondValue")
ThirdValue_Ord = MyObjectReader.GetOrdinal("ThirdValue")
End Sub
End Class
Public Module Extensions
<Extension>
Function GetValue(Of T)(rdr As SqlDataReader, i As Integer) As T
If rdr.IsDBNull(i) Then
Return Nothing
End If
Return DirectCast(rdr.GetValue(i), T)
End Function
End Module
答案 0 :(得分:2)
您应该将序数传递给GetValue
来电:
While MyObjectReader.Read()
Dim Temp = New MyObject() With {
.FirstValue = MyObjectReader.GetValue(Of Integer)(FirstValue_Ord),
.SecondValue = If(MyObjectReader.GetValue(Of String)(SecondValue_Ord), String.Empty).Trim(),
.ThirdValue = If(MyObjectReader.GetValue(Of String)(ThirdValue_Ord), String.Empty).Trim()
}
MyObjects.Add(Temp)
End While
答案 1 :(得分:0)
这是我的版本:)
Private Function Create(reader As SqlDataReader) As IEnumerable(Of MyObject)
Dim objects As New List(Of MyObject)()
Dim ordinals As New Ordinals(reader)
While reader.Read()
Dim Temp As New MyObject With
{
.FirstValue = reader.GetValueOrDefault(Of Integer)(ordinals.FirstValue),
.SecondValue = reader.GetValueOrDefault(ordinals.SecondValue, "").Trim(),
.ThirdValue = reader.GetValueOrDefault(ordinals.ThirdValue, "").Trim()
}
objects.Add(Temp)
End While
Return MyObjects
End Function
Private Class Ordinals
Public Property FirstValue As Integer
Public Property SecondValue As Integer
Public Property ThirdValue As Integer
Public Sub New(reader As SqlDataReader)
FirstValue = reader.GetOrdinal(nameOf(FirstValue))
SecondValue = reader.GetOrdinal(nameOf(SecondValue))
ThirdValue = reader.GetOrdinal(nameOf(ThirdValue))
End Sub
End Class
Public Module Extensions
<Extension>
Function GetValueOrDefault(Of T)(reader As SqlDataReader, ordinal As Integer) As T
Return reader.GetValueOrDefault(Of T)(ordinal, Nothing)
End Function
<Extension>
Function GetValueOrDefault(Of T)(reader As SqlDataReader,
ordinal As Integer,
defaultValue As T) As T
Dim value = reader(ordinal)
If value = DbNull.Value Then
Return defaultValue
End If
Return DirectCast(value, T)
End Function
End Module
因为扩展方法针对已经提取的对象执行DbNull.Value
检查,所以我们摆脱了从SqlDataReader
两次读取相同值。
SqlDataReader.IsDbNull(index)
在检查DbNull
之前读取值。
扩展方法有两个重载:
- 如果值为DbNull.Value
,则返回给定类型的默认值。 vb.net中的Nothing
是类型的默认值
- 如果值为DbNull.Value
,则需要返回默认值参数。可能性传递默认值使得创建新对象的行更短且更易读。我们摆脱了内联if
声明。
您的名为GetValue
的扩展程序有&#34;副作用&#34;。按名称,此方法的消费者希望从SqlDataReader
获得价值。因此,如果数据库查询返回DbNull.Value
,他可以期望获得NULL
,而是获得null
表示字符串或0
表示整数。名称GetValueOrDefault
的出价较少,因此您无需进入内部方法来查看正在执行的操作。