﻿Imports System.Data.Common
Imports System.Data.Odbc
Imports System.Data.OleDb
Imports System.Data.SqlClient
Imports System.Runtime.CompilerServices

Public Module DataReaderExtensions

#Region " DbDataReader "

    ''' <summary>
    ''' Gets the value of the specified column as a Boolean.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a Boolean, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetBoolean(ByVal source As DbDataReader, ByVal name As String) As Boolean
        Return source.GetBoolean(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable Boolean.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a Boolean or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableBoolean(ByVal source As DbDataReader, ByVal ordinal As Integer) As Boolean?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Boolean?), source.GetBoolean(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable Boolean.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a Boolean or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableBoolean(ByVal source As DbDataReader, ByVal name As String) As Boolean?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Boolean?), source.GetBoolean(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a byte.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a byte, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetByte(ByVal source As DbDataReader, ByVal name As String) As Byte
        Return source.GetByte(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable byte.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a byte or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableByte(ByVal source As DbDataReader, ByVal ordinal As Integer) As Byte?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Byte?), source.GetByte(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable byte.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a byte or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableByte(ByVal source As DbDataReader, ByVal name As String) As Byte?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Byte?), source.GetByte(ordinal))
    End Function

    ''' <summary>
    ''' Reads a stream of bytes from the specified column, starting at location indicated by <b>dataOffset</b>, into the buffer, starting at the location indicated by <b>bufferOffset</b>.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <param name="dataOffset">
    ''' The index within the row from which to begin the read operation.
    ''' </param>
    ''' <param name="buffer">
    ''' The buffer into which to copy the data.
    ''' </param>
    ''' <param name="bufferOffset">
    ''' The index within the buffer to which the data will be copied.
    ''' </param>
    ''' <param name="length">
    ''' The maximum number of bytes to read.
    ''' </param>
    ''' <returns>
    ''' The actual number of bytes read.
    ''' </returns>
    <Extension()>
    Public Function GetBytes(ByVal source As DbDataReader,
                             ByVal name As String,
                             ByVal dataOffset As Long,
                             ByVal buffer As Byte(),
                             ByVal bufferOffset As Integer,
                             ByVal length As Integer) As Long
        Return source.GetBytes(source.GetOrdinal(name), dataOffset, buffer, bufferOffset, length)
    End Function

    ''' <summary>
    ''' Reads a stream of bytes from the specified column, starting at location indicated by <b>dataOffset</b>, into the buffer, starting at the location indicated by <b>bufferOffset</b>.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <param name="dataOffset">
    ''' The index within the row from which to begin the read operation.
    ''' </param>
    ''' <param name="buffer">
    ''' The buffer into which to copy the data.
    ''' </param>
    ''' <param name="bufferOffset">
    ''' The index within the buffer to which the data will be copied.
    ''' </param>
    ''' <param name="length">
    ''' The maximum number of bytes to read.
    ''' </param>
    ''' <returns>
    ''' The actual number of bytes read if the field has a value, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    <Extension()>
    Public Function GetNullableBytes(ByVal source As DbDataReader,
                                     ByVal ordinal As Integer,
                                     ByVal dataOffset As Long,
                                     ByVal buffer As Byte(),
                                     ByVal bufferOffset As Integer,
                                     ByVal length As Integer) As Long?
        Return If(source.IsDBNull(ordinal),
                  DirectCast(Nothing, Long?),
                  source.GetBytes(ordinal,
                                  dataOffset,
                                  buffer,
                                  bufferOffset,
                                  length))
    End Function

    ''' <summary>
    ''' Reads a stream of bytes from the specified column, starting at location indicated by <b>dataOffset</b>, into the buffer, starting at the location indicated by <b>bufferOffset</b>.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <param name="dataOffset">
    ''' The index within the row from which to begin the read operation.
    ''' </param>
    ''' <param name="buffer">
    ''' The buffer into which to copy the data.
    ''' </param>
    ''' <param name="bufferOffset">
    ''' The index within the buffer to which the data will be copied.
    ''' </param>
    ''' <param name="length">
    ''' The maximum number of bytes to read.
    ''' </param>
    ''' <returns>
    ''' The actual number of bytes read if the field has a value, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    <Extension()>
    Public Function GetNullableBytes(ByVal source As DbDataReader,
                                     ByVal name As String,
                                     ByVal dataOffset As Long,
                                     ByVal buffer As Byte(),
                                     ByVal bufferOffset As Integer,
                                     ByVal length As Integer) As Long?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal),
                  DirectCast(Nothing, Long?),
                  source.GetBytes(ordinal,
                                  dataOffset,
                                  buffer,
                                  bufferOffset,
                                  length))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a single character.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a single character, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetChar(ByVal source As DbDataReader, ByVal name As String) As Char
        Return source.GetChar(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable single character.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a single character or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableChar(ByVal source As DbDataReader, ByVal ordinal As Integer) As Char?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Char?), source.GetChar(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable single character.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a single character or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableChar(ByVal source As DbDataReader, ByVal name As String) As Char?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Char?), source.GetChar(ordinal))
    End Function

    ''' <summary>
    ''' Reads a stream of characters from the specified column, starting at location indicated by <b>dataOffset</b>, into the buffer, starting at the location indicated by <b>bufferOffset</b>.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <param name="dataOffset">
    ''' The index within the row from which to begin the read operation.
    ''' </param>
    ''' <param name="buffer">
    ''' The buffer into which to copy the data.
    ''' </param>
    ''' <param name="bufferOffset">
    ''' The index within the buffer to which the data will be copied.
    ''' </param>
    ''' <param name="length">
    ''' The maximum number of characters to read.
    ''' </param>
    ''' <returns>
    ''' The actual number of characters read.
    ''' </returns>
    <Extension()>
    Public Function GetChars(ByVal source As DbDataReader,
                             ByVal name As String,
                             ByVal dataOffset As Long,
                             ByVal buffer As Char(),
                             ByVal bufferOffset As Integer,
                             ByVal length As Integer) As Long?
        Return source.GetChars(source.GetOrdinal(name), dataOffset, buffer, bufferOffset, length)
    End Function

    ''' <summary>
    ''' Reads a stream of characters from the specified column, starting at location indicated by <b>dataOffset</b>, into the buffer, starting at the location indicated by <b>bufferOffset</b>.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <param name="dataOffset">
    ''' The index within the row from which to begin the read operation.
    ''' </param>
    ''' <param name="buffer">
    ''' The buffer into which to copy the data.
    ''' </param>
    ''' <param name="bufferOffset">
    ''' The index within the buffer to which the data will be copied.
    ''' </param>
    ''' <param name="length">
    ''' The maximum number of characters to read.
    ''' </param>
    ''' <returns>
    ''' The actual number of characters read if the field has a value, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    <Extension()>
    Public Function GetNullableChars(ByVal source As DbDataReader,
                                     ByVal ordinal As Integer,
                                     ByVal dataOffset As Long,
                                     ByVal buffer As Char(),
                                     ByVal bufferOffset As Integer,
                                     ByVal length As Integer) As Long?
        Return If(source.IsDBNull(ordinal),
                  DirectCast(Nothing, Long?),
                  source.GetChars(ordinal,
                                  dataOffset,
                                  buffer,
                                  bufferOffset,
                                  length))
    End Function

    ''' <summary>
    ''' Reads a stream of characters from the specified column, starting at location indicated by <b>dataOffset</b>, into the buffer, starting at the location indicated by <b>bufferOffset</b>.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <param name="dataOffset">
    ''' The index within the row from which to begin the read operation.
    ''' </param>
    ''' <param name="buffer">
    ''' The buffer into which to copy the data.
    ''' </param>
    ''' <param name="bufferOffset">
    ''' The index within the buffer to which the data will be copied.
    ''' </param>
    ''' <param name="length">
    ''' The maximum number of characters to read.
    ''' </param>
    ''' <returns>
    ''' The actual number of characters read if the field has a value, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    <Extension()>
    Public Function GetNullableChars(ByVal source As DbDataReader,
                                     ByVal name As String,
                                     ByVal dataOffset As Long,
                                     ByVal buffer As Char(),
                                     ByVal bufferOffset As Integer,
                                     ByVal length As Integer) As Long?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal),
                  DirectCast(Nothing, Long?),
                  source.GetChars(ordinal,
                                  dataOffset,
                                  buffer,
                                  bufferOffset,
                                  length))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a <see cref="DateTime" />.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>DateTime</b>, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetDateTime(ByVal source As DbDataReader, ByVal name As String) As DateTime
        Return source.GetDateTime(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="DateTime" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>DateTime</b> object or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableDateTime(ByVal source As DbDataReader, ByVal ordinal As Integer) As Date?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Date?), source.GetDateTime(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="DateTime" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>DateTime</b> object or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableDateTime(ByVal source As DbDataReader, ByVal name As String) As Date?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Date?), source.GetDateTime(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a <see cref="Decimal" />.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>Decimal</b>, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetDecimal(ByVal source As DbDataReader, ByVal name As String) As Decimal
        Return source.GetDecimal(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="Decimal" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>Decimal</b> object or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableDecimal(ByVal source As DbDataReader, ByVal ordinal As Integer) As Decimal?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Decimal?), source.GetDecimal(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="Decimal" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>Decimal</b> object or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableDecimal(ByVal source As DbDataReader, ByVal name As String) As Decimal?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Decimal?), source.GetDecimal(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a double-precision floating point number.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a double-precision floating point number, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetDouble(ByVal source As DbDataReader, ByVal name As String) As Double
        Return source.GetDouble(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable double-precision floating point number.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a double-precision floating point number or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableDouble(ByVal source As DbDataReader, ByVal ordinal As Integer) As Double?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Double?), source.GetDouble(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable double-precision floating point number.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a double-precision floating point number or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableDouble(ByVal source As DbDataReader, ByVal name As String) As Double?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Double?), source.GetDouble(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a single-precision floating point number.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a single-precision floating point number, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetFloat(ByVal source As DbDataReader, ByVal name As String) As Single
        Return source.GetFloat(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable single-precision floating point number.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a single-precision floating point number or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableFloat(ByVal source As DbDataReader, ByVal ordinal As Integer) As Single?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Single?), source.GetFloat(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable single-precision floating point number.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a single-precision floating point number or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableFloat(ByVal source As DbDataReader, ByVal name As String) As Single?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Single?), source.GetFloat(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a globally-unique identifier (GUID).
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a globally-unique identifier (GUID), or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetGuid(ByVal source As DbDataReader, ByVal name As String) As Guid
        Return source.GetGuid(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable globally-unique identifier (GUID).
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a globally-unique identifier (GUID) or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableGuid(ByVal source As DbDataReader, ByVal ordinal As Integer) As Guid?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Guid?), source.GetGuid(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable globally-unique identifier (GUID).
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a globally-unique identifier (GUID) or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableGuid(ByVal source As DbDataReader, ByVal name As String) As Guid?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Guid?), source.GetGuid(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a 16-bit signed integer.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a 16-bit signed integer, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetInt16(ByVal source As DbDataReader, ByVal name As String) As Short
        Return source.GetInt16(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable 16-bit signed integer.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a 16-bit signed integer or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableInt16(ByVal source As DbDataReader, ByVal ordinal As Integer) As Short?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Short?), source.GetInt16(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable 16-bit signed integer.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a 16-bit signed integer or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableInt16(ByVal source As DbDataReader, ByVal name As String) As Short?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Short?), source.GetInt16(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a 32-bit signed integer.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a 32-bit signed integer, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetInt32(ByVal source As DbDataReader, ByVal name As String) As Integer
        Return source.GetInt32(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable 32-bit signed integer.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a 32-bit signed integer or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableInt32(ByVal source As DbDataReader, ByVal ordinal As Integer) As Integer?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Integer?), source.GetInt32(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable 32-bit signed integer.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a 32-bit signed integer or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableInt32(ByVal source As DbDataReader, ByVal name As String) As Integer?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Integer?), source.GetInt32(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a 64-bit signed integer.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a 64-bit signed integer, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetInt64(ByVal source As DbDataReader, ByVal name As String) As Long
        Return source.GetInt64(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable 64-bit signed integer.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a 64-bit signed integer or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableInt64(ByVal source As DbDataReader, ByVal ordinal As Integer) As Long?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Long?), source.GetInt64(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable 64-bit signed integer.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a 64-bit signed integer or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableInt64(ByVal source As DbDataReader, ByVal name As String) As Long?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Long?), source.GetInt64(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a string.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a string, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetString(ByVal source As DbDataReader, ByVal name As String) As String
        Return source.GetString(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable string.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a string or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableString(ByVal source As DbDataReader, ByVal ordinal As Integer) As String
        Return If(source.IsDBNull(ordinal), Nothing, source.GetString(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable string.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a string or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableString(ByVal source As DbDataReader, ByVal name As String) As String
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), Nothing, source.GetString(ordinal))
    End Function

#End Region 'DbDataReader

#Region " OdbcDataReader "

    ''' <summary>
    ''' Gets the value of the specified column as a <see cref="DateTime" />.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>DateTime</b>, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetDate(ByVal source As OdbcDataReader, ByVal name As String) As Date
        Return source.GetDate(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="DateTime" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>DateTime</b> or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableDate(ByVal source As OdbcDataReader, ByVal ordinal As Integer) As Date?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Date?), source.GetDateTime(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="DateTime" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>DateTime</b> or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableDate(ByVal source As OdbcDataReader, ByVal name As String) As Date?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, Date?), source.GetDateTime(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a <see cref="TimeSpan" />.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>TimeSpan</b>, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetTime(ByVal source As OdbcDataReader, ByVal name As String) As TimeSpan
        Return source.GetTime(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="TimeSpan" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>TimeSpan</b> or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableTime(ByVal source As OdbcDataReader, ByVal ordinal As Integer) As TimeSpan?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, TimeSpan?), source.GetTime(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="TimeSpan" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>TimeSpan</b> or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableTime(ByVal source As OdbcDataReader, ByVal name As String) As TimeSpan?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, TimeSpan?), source.GetTime(ordinal))
    End Function

#End Region 'OdbcDataReader

#Region " OleDbDataReader "

    ''' <summary>
    ''' Gets the value of the specified column as a <see cref="TimeSpan" />.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>TimeSpan</b>, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetTimeSpan(ByVal source As OleDbDataReader, ByVal name As String) As TimeSpan
        Return source.GetTimeSpan(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="TimeSpan" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>TimeSpan</b> or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableTimeSpan(ByVal source As OleDbDataReader, ByVal ordinal As Integer) As TimeSpan?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, TimeSpan?), source.GetTimeSpan(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="TimeSpan" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>TimeSpan</b> or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableTimeSpan(ByVal source As OleDbDataReader, ByVal name As String) As TimeSpan?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, TimeSpan?), source.GetTimeSpan(ordinal))
    End Function

#End Region 'OleDbDataReader

#Region " SqlDataReader "

    ''' <summary>
    ''' Gets the value of the specified column as a<see cref="DateTimeOffset" />.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>DateTimeOffset</b>, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetDateTimeOffset(ByVal source As SqlDataReader, ByVal name As String) As DateTimeOffset
        Return source.GetDateTimeOffset(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="DateTimeOffset" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>DateTimeOffset</b> or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableDateTimeOffset(ByVal source As SqlDataReader, ByVal ordinal As Integer) As DateTimeOffset?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, DateTimeOffset?), source.GetDateTimeOffset(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="DateTimeOffset" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>DateTimeOffset</b> or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableDateTimeOffset(ByVal source As SqlDataReader, ByVal name As String) As DateTimeOffset?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, DateTimeOffset?), source.GetDateTimeOffset(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a <see cref="TimeSpan" />.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column.
    ''' </returns>
    ''' <remarks>
    ''' <para>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>TimeSpan</b>, or an exception is generated.
    ''' </para>
    ''' <para>
    ''' Call <see cref="DbDataReader.IsDBNull">IsDBNull</see> to check for null values before calling this method.
    ''' </para>
    ''' </remarks>
    <Extension()>
    Public Function GetTimeSpan(ByVal source As SqlDataReader, ByVal name As String) As TimeSpan
        Return source.GetTimeSpan(source.GetOrdinal(name))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="TimeSpan" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="ordinal">
    ''' The zero-based column ordinal.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>TimeSpan</b> or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableTimeSpan(ByVal source As SqlDataReader, ByVal ordinal As Integer) As TimeSpan?
        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, TimeSpan?), source.GetTimeSpan(ordinal))
    End Function

    ''' <summary>
    ''' Gets the value of the specified column as a nullable <see cref="TimeSpan" /> object.
    ''' </summary>
    ''' <param name="source">
    ''' The data reader from which to get the data.
    ''' </param>
    ''' <param name="name">
    ''' The name of the column.
    ''' </param>
    ''' <returns>
    ''' The value of the column if it has one, or a null reference (<b>Nothing</b> in Visual Basic) if the column contains <see cref="DBNull.Value" />.
    ''' </returns>
    ''' <remarks>
    ''' No conversions are performed; therefore, the data retrieved must already be a <b>TimeSpan</b> or <b>DBNull.Value</b>, or an exception is generated.
    ''' </remarks>
    <Extension()>
    Public Function GetNullableTimeSpan(ByVal source As SqlDataReader, ByVal name As String) As TimeSpan?
        Dim ordinal As Integer = source.GetOrdinal(name)

        Return If(source.IsDBNull(ordinal), DirectCast(Nothing, TimeSpan?), source.GetTimeSpan(ordinal))
    End Function

#End Region 'SqlDataReader

End Module
