DataReader ordinal-based lookups vs named lookups

前端 未结 4 1752
一个人的身影
一个人的身影 2020-12-18 06:34

Microsoft (and many developers) claim that the SqlDataReader.GetOrdinal method improves the performance of retrieving values from a DataReader versus using named lookups ie.

相关标签:
4条回答
  • 2020-12-18 06:58

    Microsoft recommends not calling GetOrdinal within a loop.

    That would include indirect calls with the string indexer.

    You can use GetOrdinal at the top of your loop put the ordinals in an array and have the indexes in the array be const or have an enum for them (no GetOrdinal at all) or use GetOrdinal into individual variables with descriptive names.

    Only if your sets are small would I really consider this to be premature optimization.

    It's apparently a 3% penalty.

    0 讨论(0)
  • 2020-12-18 07:05

    Yes and no.

    If you're dealing with a massive amount of data then you'd certainly benefit from using the ordinals rather than the column names.

    Otherwise, keep it simple, readable, and somewhat safer - and stick with the column names.

    Optimize only when you need to.

    0 讨论(0)
  • 2020-12-18 07:06

    I created a wrapper for SqlDataReader that stores orindals in a dictionary with the column name as the key.

    It gives me ordinal performance gains while keeping the code more readable and less likely to break if someone changes the column order returned from stored procedures.

    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
    
    0 讨论(0)
  • 2020-12-18 07:16

    Any difference will be more than outweighed by maintenance overhead.

    If you have that much data that it makes a noticeable difference, I'd suggest you have too much data in your client code. Or this is when you consider use ordinals rather than names

    0 讨论(0)
提交回复
热议问题