Microsoft(以及许多开发人员)claim SqlDataReader.GetOrdinal方法提高了从DataReader检索值的性能,而不是使用命名查找。读取器[ “的ColumnName”]。问题是如果处理小的分页记录集,真正的性能差异是什么?是否值得在整个代码中查找和引用序数索引的额外开销?
答案 0 :(得分:6)
Microsoft recommends not calling GetOrdinal within a loop.
那将包括使用字符串索引器的间接调用。
您可以在循环顶部使用GetOrdinal将序数放在数组中,并使数组中的索引为const或具有枚举(完全没有GetOrdinal)或将GetOrdinal用于具有描述性名称的单个变量。
只有当你的设置很小时,我才真的认为这是过早的优化。
答案 1 :(得分:5)
任何差异都不会超过维护费用。
如果你有那么多数据会产生显着差异,我建议你的客户端代码中有太多数据。或者这是当你考虑使用序数而不是名字
时答案 2 :(得分:2)
是和否。
如果您正在处理大量数据,那么您肯定会从使用序数而不是列名中受益。
否则,请保持简单,可读,更安全 - 并坚持使用列名称。
仅在您需要时进行优化。
答案 3 :(得分:-1)
我为SqlDataReader创建了一个包装器,它将orindals存储在一个以列名作为键的字典中。
它为我提供了序数性能提升,同时保持代码更具可读性,并且如果有人更改了从存储过程返回的列顺序,则不太可能中断。
Friend Class DataReader
Implements IDisposable
Private _reader As SqlDataReader
Private _oridinals As Dictionary(Of String, Integer)
Private Shared _stringComparer As StringComparer = StringComparer.OrdinalIgnoreCase 'Case in-sensitive
Public Sub New(reader As SqlDataReader)
Me._reader = reader
Me.SetOrdinals()
End Sub
Private Sub SetOrdinals()
Me._oridinals = New Dictionary(Of String, Integer)(_stringComparer)
For i As Integer = 0 To Me._reader.FieldCount - 1
Me._oridinals.Add(Me._reader.GetName(i), i)
Next
End Sub
Public Function Read() As Boolean
Return Me._reader.Read()
End Function
Public Function NextResult() As Boolean
Dim value = Me._reader.NextResult()
If value Then
Me.SetOrdinals()
End If
Return value
End Function
Default Public ReadOnly Property Item(name As String) As Object
Get
Return Me._reader(Me.GetOrdinal(name))
End Get
End Property
Public Function GetOrdinal(name As String) As Integer
Return Me._oridinals.Item(name)
End Function
Public Function GetInteger(name As String) As Integer
Return Me._reader.GetInt32(Me.GetOrdinal(name))
End Function
Public Function GetString(ordinal As Integer) As String
Return Me._reader.GetString(ordinal)
End Function
Public Function GetString(name As String) As String
Return Me._reader.GetString(Me.GetOrdinal(name))
End Function
Public Function GetDate(name As String) As Date
Return Me._reader.GetDateTime(Me.GetOrdinal(name))
End Function
Public Function GetDateNullable(name As String) As Nullable(Of Date)
Dim o = Me._reader.GetValue(Me.GetOrdinal(name))
If o Is System.DBNull.Value Then
Return Nothing
Else
Return CDate(o)
End If
End Function
Public Function GetDecimal(name As String) As Decimal
Return Me._reader.GetDecimal(Me.GetOrdinal(name))
End Function
Public Function GetBoolean(name As String) As Boolean
Return Me._reader.GetBoolean(Me.GetOrdinal(name))
End Function
Public Function GetByteArray(name As String) As Byte()
Return CType(Me._reader.GetValue(Me.GetOrdinal(name)), Byte())
End Function
Public Function GetBooleanFromYesNo(name As String) As Boolean
Return Me._reader.GetString(Me.GetOrdinal(name)) = "Y"
End Function
'Disposable Code
End Class