ADO.NET. Какова наилучшая практика для получения значений datareader?

Просто интересно, что лучше всего подходит для получения значений datareader. Например:

Я делал это:

MyValue = Dr("ColumnName")

Но заметили, что другие люди делают:

MyValue = Dr.GetString("ColumnName")

Мне интересно узнать преимущества второго метода

Ответы

Ответ 1

Я использую обертку, которая делает подобную вещь некоторое время, что делает трюк красиво.


     RowHelper helper = new RowHelper(Dr);
     MyValue = helper.IntColumn("ColumnName");

Приятная вещь в этом - помощник вернет предопределенные значения по умолчанию для столбцов NULL (это настраивается). У меня есть методы для всех основных типов данных SQL.

Чтобы ответить на ваш вопрос, второй метод имеет некоторые накладные расходы на бокс /unboxing, но, вероятно, это будет пустой тратой времени, чтобы оптимизировать это для типичного бизнес-приложения.

Ответ 2

Метод DbDataReader.GetString(int) может использоваться только в том случае, если вы знаете индекс столбца. Использование DbDataReader.GetString( "ColumnName" ) невозможно, так как такой перегрузки нет. То есть у вас есть следующие два варианта:

 string myValue1 = (string) Dr["ColumnName"];
 string myValue2 = Dr.GetString(columIndex);

Первая строка внутренне вызывает DbDataReader.GetOrdinal( "ColumnName" ).

Ответ 3

Я сделал несколько общих методов расширения для этого:

public static class DataReaderExtensions
{
    public static T GetValueOrNull<T>(this IDataRecord reader, string fieldName)
        where T : class
    {
        int index = reader.GetOrdinal(fieldName);
        return reader.IsDBNull(index) ? null : (T)reader.GetValue(index);
    }
}

Вы получаете изображение... У меня также есть GetValueOrDefault для типов значений.

Ответ 4

DataReader возвращает объект типа, поэтому вам нужно указать значение из DataReader для любого типа MyValue, так что в случае int

MyValue = (int)Dr("ColumnName");

или

MyValue = Convert.ToInt(Dr("ColumnName"));

или

MyValue = Dr("ColumnName").ToInt();

Я не уверен в различиях в производительности, но я думаю, что это может быть истолковано как микрооптимизация, если не работать с чрезвычайно большими наборами данных

Ответ 5

Использование AutoMapper:

var dataReader = ... // Execute a data reader
var views = Mapper.Map<IDataReader, IEnumerable<SomeView>>(_dataReader);