Лучшие практики DataReader

Похоже на этот вопрос, но ответы так и не дошли до того, что я хочу знать. Существуют ли какие-либо стандарты для получения значений из DataReader? I.e., это

dataReader.GetString(dataReader.GetOrdinal("ColumnName"));

считается лучше/хуже/так же, как это?

(string) dataReader["ColumnName"];

Ответ 1

Вот как это сделать:

Int32 ordinal = dataReader.GetOrdinal("ColumnName");

if (!dataReader.IsDBNull(ordinal))
    yourString = dataReader.GetString(ordinal);

Важно проверить для DBNull, как я показал выше, потому что если поле имеет нулевое значение в DataReader, оно генерирует исключение при попытке получить его.

Ответ 2

Я сделал некоторые методы расширения, чтобы позволить мне рассматривать IDataReader как перечислимый и иметь дело с DbNull, возвращая nullable ints и т.д. Это позволяет мне проверять значение null и применять значение по умолчанию с помощью С# ??.

/// <summary>
/// Returns an IEnumerable view of the data reader.
/// WARNING: Does not support readers with multiple result sets.
/// The reader will be closed after the first result set is read.
/// </summary>
public static IEnumerable<IDataRecord> AsEnumerable(this IDataReader reader)
{
    if (reader == null)
        throw new ArgumentNullException("reader");

    using (reader)
    {
        while (reader.Read())
        {
            yield return reader;
        }
    }
}

public static int? GetNullableInt32(this IDataRecord dr, string fieldName)
{
    return GetNullableInt32(dr, dr.GetOrdinal(fieldName));
}

public static int? GetNullableInt32(this IDataRecord dr, int ordinal)
{
    return dr.IsDBNull(ordinal) ? null : (int?)dr.GetInt32(ordinal);
}

... и т.д. для других методов GetDataType() на IDataReader.