While CommitReader.Read()
Yield New Commit() With {
.FirstValue = CommitReader.GetInt32(CommitReader.GetOrdinal("FirstValue")),
.SecondValue = CommitReader.GetString(CommitReader.GetOrdinal("SecondValue")).Trim(),
'Lots of values
End While
我知道我可以做这样的事情;然而,有24个属性,我想尽可能使这部分干净
While CommitReader.Read()
new Commit (){
Dim index As Integer = reader.GetOrdinal("FirstValue")
If reader.IsDBNull(index) Then
FirstValue = String.Empty
Else
FirstValue = reader(index)
End If
index = reader.GetOrdinal("SecondValue")
If reader.IsDBNull(index) Then
SecondValue = String.Empty
Else
SecondValue = reader(index)
End If
}
End While
有没有更好的方法来处理这类事情?我主要是一个C#开发人员,所以如果语法有点遗憾,我会在VB中使用它。
答案 0 :(得分:2)
令人遗憾的是,SqlDataReader没有像DataRow那样的通用Field扩展方法,但你可以定义自己的扩展方法(必须在VB.NET的模块中)来帮助null检查,可能是这样的:
<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
使用类似这样的东西:
While CommitReader.Read()
Yield New Commit() With {
.FirstValue = CommitReader.GetValue(Of Integer?)(CommitReader.GetOrdinal("FirstValue")),
.SecondValue = CommitReader.GetValue(Of String)(CommitReader.GetOrdinal("SecondValue")),
'Lots of values
End While
我还没有对此进行全面测试,以确保它能够正确处理所有数据类型(可能值得一看DataRowExtensions.Field以了解它是如何做到的)。
请注意,您使用String.Empty作为&#34; null&#34;字符串的值,虽然这将使用Nothing / null(我还必须删除.Trim调用以避免NRE)。如果你想要空字符串,你可以使用(添加Trim):
.SecondValue = If(CommitReader.GetValue(Of String)(CommitReader.GetOrdinal("SecondValue")), String.Empty).Trim()
您可能还希望将GetOrdinal调用移出循环以提高性能。
答案 1 :(得分:1)
显然,您的代码if ... else ...
条件会重复
所以你可以用另一种方法提取它。
对于您的情况,通用扩展方法似乎是很好的候选者。
Public Module Extensions
<Extension>
Public Function GetValueOrDefault(Of T)(originalValue As object,
defaultValue As T) As T
If originalValue = DbNull.Value Then
Return defaultValue
End If
return DirectCast(originalValue, T)
End Function
End Module
然后使用它:
While CommitReader.Read() = True
Dim temp = new Commit With
{
Dim index As Integer = reader.GetOrdinal("FirstValue")
FirstValue = reader(index).GetValueOrDefault(String.Empty)
Dim index As Integer = reader.GetOrdinal("SecondValue")
FirstValue = reader(index).GetValueOrDefault(String.Empty)
}
End While
您可以创建另一个重载,如果它是DbNull
<Extension>
Public Function GetValueOrDefault(Of T)(originalValue As object) As T
Return originalValue.GetValueOrDefault(Nothing)
End Function
vb.net中的 Nothing
是默认值,对于null
,引用类型为Integer
,例如0
。
要使用此重载,您需要明确提供类型参数
While CommitReader.Read() = True
Dim temp = new Commit With
{
Dim index As Integer = reader.GetOrdinal("FirstValue")
FirstValue = reader(index).GetValueOrDefault(Of String)()
Dim index As Integer = reader.GetOrdinal("SecondValue")
FirstValue = reader(index).GetValueOrDefault(Of String)()
}
End While
请注意,您的解决方案执行reader
两次,检查是否为空并且读取值。这可能会导致“微小”的性能问题。
因此,在上面的扩展方法中,我们只读取一次值,然后检查DbNull
的值。
答案 2 :(得分:0)
如果将字符串与Null连接,则会得到字符串:
FirstValue = reader(index) & ""
有点“不专业”,但如果您正在做的就是将可能的Null转换为空字符串,则会节省大量编码时间。但是很容易忘记,因此可能会出现以后的数据相关错误。