2009-12-06 3 views
9

Как и в случае с this question, но ответы так и не получили, что я хочу знать. Существуют ли какие-либо стандарты для получения значений из DataReader? I.e., isDataReader best-practices

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

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

(string) dataReader["ColumnName"]; 

ответ

11

Вот так, что я делаю это:

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

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

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

+0

Абсолютно согласовано. Я больше спрашиваю о синтаксических различиях получения фактического значения, используя функциональность DataReaders Item [] и используя предоставленные методы DataReader.Get . –

+0

Я всегда использую datareader ["column1"], гораздо приятнее читать. –

+3

Поскольку формат 'datareader [" column "]' возвращает объект и не является строго типизированным, я не думаю, что вы получите исключение, если данные будут 'DbNull'. Вы просто получите 'DbNull.Value', приведённый к' object'. Конечно, вы можете получить исключение позже, когда вы попытаетесь использовать это значение, если вы сначала не выполните проверку Convert.IsDbNull. –

9

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

/// <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.

+0

Вы можете просто называть 'reader.Cast ()'. – SLaks

+1

Ну, если бы у 'IDataReader' было что-то общее с' IEnumerable'. Однако, это не так. Подпись есть: 'public interface IDataReader: IDisposable, IDataRecord' –

+0

Приятно, но вы можете закрыть читателя после:' while (reader.Read()) 'loop –