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);