只是想知道获取数据读取器值的最佳实践是什么。例如:
我一直在这样做:
MyValue = Dr("ColumnName")
但是注意到其他人在做:
MyValue = Dr.GetString("ColumnName")
我很想知道第二种方法的好处
只有知道列的索引才能使用 DbDataReader.GetString(int) 方法。使用 DbDataReader.GetString("ColumnName") 是不可能的,因为没有这样的重载。即你有以下两种选择:
string myValue1 = (string) Dr["ColumnName"];
string myValue2 = Dr.GetString(columIndex);
第一行在内部调用 DbDataReader.GetOrdinal("ColumnName")。
一段时间以来,我一直在使用一个做类似事情的包装器,它很好地完成了这个技巧。
RowHelper helper = new RowHelper(Dr);
MyValue = helper.IntColumn("ColumnName");
这样做的好处是帮助程序将为 NULL 列返回预定义的默认值(这是可配置的)。我有所有主要 SQL 数据类型的方法。
为了回答您的问题,第二种方法有一些装箱/拆箱开销,但为典型的业务应用程序优化它可能会浪费您的时间。
我为此做了几个通用的扩展方法:
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
for 值类型。
DataReader 返回类型对象,因此您需要将 DataReader 中的值转换为 MyValue 的任何类型,在 int 的情况下
MyValue = (int)Dr("ColumnName");
或者
MyValue = Convert.ToInt(Dr("ColumnName"));
或者
MyValue = Dr("ColumnName").ToInt();
我不确定性能差异,但我认为这可以解释为微优化,除非处理非常大的数据集
使用自动映射器:
var dataReader = ... // Execute a data reader
var views = Mapper.Map<IDataReader, IEnumerable<SomeView>>(_dataReader);