Vb.net 为什么这个返回的索引是越界异常
当我到达读循环时,我得到一个索引越界错误。我认为这取决于读者顺序值,但我不确定为什么我会得到它Vb.net 为什么这个返回的索引是越界异常,vb.net,Vb.net,当我到达读循环时,我得到一个索引越界错误。我认为这取决于读者顺序值,但我不确定为什么我会得到它 Private Function Create(Reader As SqlDataReader) As IEnumerable(Of MyObject) SetOrdinals(MyObjectReader) Dim MyObjects = New List(Of MyObject) While MyObjectReader.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
Private函数Create(读取器作为SqlDataReader)作为IEnumerable(MyObject的)
集合序号(MyObjectReader)
Dim MyObjects=新列表(MyObject)
而MyObjectReader.Read()
Dim Temp=新的MyObject()和{
.FirstValue=MyObjectReader.GetValue(整数的)(MyObjectReader(FirstValue_Ord)),
.SecondValue=If(MyObjectReader.GetValue(字符串的)(MyObjectReader(SecondValue_Ord)),String.Empty.Trim(),
.ThirdValue=If(MyObjectReader.GetValue(字符串的)(MyObjectReader(ThirdValue_Ord)),String.Empty).Trim(),
MyObject.Add(临时)
结束时
返回对象
端函数
私有子集合序号(MyObjectReader作为SqlDataReader)
FirstValueOrd=MyObjectReader.GetOrdinal(“FirstValue”)
SecondValue_Ord=MyObjectReader.getOrdinl(“SecondValue”)
ThirdValue_Ord=MyObjectReader.GetOrdinal(“ThirdValue”)
端接头
末级
公共模块扩展
函数GetValue(Of T)(rdr作为SqlDataReader,i作为整数)作为T
如果rdr.IsDBNull(i)那么
一无所获
如果结束
返回DirectCast(rdr.GetValue(i),T)
端函数
端模块
您应该将序号传递给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
这是我的版本:)
Private函数Create(读取器作为SqlDataReader)作为IEnumerable(MyObject的)
将对象调整为新列表(MyObject)()
变暗序数作为新序数(读取器)
而reader.Read()
Dim Temp作为新的MyObject,具有
{
.FirstValue=reader.GetValuerDefault(整数的)(序数.FirstValue),
.SecondValue=reader.GetValueOrDefault(ordinals.SecondValue,”).Trim(),
.ThirdValue=reader.GetValueOrDefault(ordinals.ThirdValue,”).Trim()
}
对象。添加(临时)
结束时
返回对象
端函数
私有类序数
公共属性值为整数
公共属性值为整数
公共属性第三个值为整数
Public Sub New(读卡器作为SqlDataReader)
FirstValue=reader.GetOrdinal(nameOf(FirstValue))
SecondValue=reader.GetOrdinal(nameOf(SecondValue))
ThirdValue=reader.GetOrdinal(名称(ThirdValue))
端接头
末级
公共模块扩展
函数getValuerDefault(Of T)(读取器为SqlDataReader,序数为整数)为T
返回读取器.getValuerDefault(共T个)(序号,无)
端函数
函数getValuerDefault(Of T)(读取器为SqlDataReader,
序号为整数,
默认值为T)为T
尺寸值=读卡器(序号)
如果value=DbNull.value,则
返回默认值
如果结束
返回DirectCast(值,T)
端函数
端模块
因为扩展方法对已经提取的对象执行DbNull.Value
检查,所以我们避免了从SqlDataReader
中两次读取相同的值SqlDataReader.IsDbNull(index)
在检查DbNull
之前读取值
扩展方法有两个重载:-如果值为
DbNull,则返回给定类型的默认值。vb.net中的value
Nothing
是类型的默认值。-如果值为
DbNull,则将参数作为默认值返回。value
。传递默认值的可能性使创建新对象的行更短,可读性更强。我们去掉了内联if
语句
名为
GetValue
的扩展方法具有“副作用”.By name此方法的使用者希望从SqlDataReader
中获取值。因此,如果数据库查询返回NULL
,他可以期望获取DbNull.value
,但相反,对于字符串,他会获取NULL
,对于整数,他会获取0
。nameGetValueOrDefault
几乎没有更多信息,因此您不需要这样做进入方法以检查正在执行的操作。很抱歉,我没有完全复制代码。实际代码使用Ordinal@Robert不同之处在于,参数应该只是序号-FirstValue\u Ord
,而不是MyObjectReader(FirstValue\u Ord)
。看起来你在重新发明轮子!SqlDataReader
已经有了名为GetString
、GetInteger
等的方法。它们做的和你的GetValue
方法做的一样。@ChrisDunaway很抱歉这么晚才回来。GetString
等方法需要空检查,这就是我建议的原因d-中的GetValue
扩展类似于DataRow
的扩展方法。有更好的方法处理吗?
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