.NET SqlDataReader项[]与GetString(GetOrdinal())的比较?

.NET SqlDataReader项[]与GetString(GetOrdinal())的比较?,.net,.net,使用SqlDataReader类,以下各项之间的功能差异是什么(如果有的话): (string) dataReader["MyFieldName"]; 及 在第一种情况下,您正在强制转换,尤其是对于值类型(涉及取消装箱)而言,这非常难看。就我个人而言,我总是使用第二种方法,这是我向您推荐的方法。抛开问题不谈,对于单一的调用,没有任何问题。索引器将调用,然后调用相应的Get方法以获取值(请注意,使用序号调用Get方法要比使用带字段名的索引器更快) 但是,这将导致每次查找序号。如果您以只向前、只读

使用
SqlDataReader
类,以下各项之间的功能差异是什么(如果有的话):

(string) dataReader["MyFieldName"];


在第一种情况下,您正在强制转换,尤其是对于值类型(涉及取消装箱)而言,这非常难看。就我个人而言,我总是使用第二种方法,这是我向您推荐的方法。

抛开问题不谈,对于单一的调用,没有任何问题。索引器将调用,然后调用相应的
Get
方法以获取值(请注意,使用序号调用
Get
方法要比使用带字段名的索引器更快)

但是,这将导致每次查找序号。如果您以只向前、只读的方式(这正是实例要做的)遍历多个记录,那么只需执行一次即可减少查找的开销

你可以这样做:

// Move to the first record.  If no records, get out.
if (!dataReader.Read()) return;

// Before the loop.  Can do this for any other fields being
// accessed in the loop as well.
int myFieldNameOrdinal = dataReader.GetOrdinal("MyFieldName");

// Process the records.  Remember, already on the first record, so
// use do/while here.
do
{
    // Do something with your field.
    Console.WriteLine(dataReader.GetString(myFieldNameOrdinal));
} while (dataReader.Read());

处理空值时:

// Will throw an InvalidCastException 
// Exception Message will be "Unable to cast object of type System.DBNull
// to System.String 
(string) dataReader["MyFieldName"]; 

// Will throw a SqlNullValueException
// Exception Message will be "Data is Null. This method or property
// cannot be called on Null values."
dataReader.GetString(dataReader.GetOrdinal("MyFieldName"));

“意外发现”是一种很好的发现方法。

作为casperOne答案的替代方法,可以很容易地减少在应用程序的生命周期中每出现一次顺序查找。也可以不用手动维护变量来记录每个索引

下面的代码要求每个类有一个查询,如果您想在一个类中处理多个查询,那么实现起来就足够容易了

从一个字段开始:

static readonly ConcurrentDictionary<string, int> OrdinalMap = 
            new ConcurrentDictionary<string, int>();

现在,您可以使用线程安全的O(1)查找序数,而无需维护任何手动变量映射或常量用法,如果您更改查询,它们将打破世界。这并不重要,只是为了清楚起见,由于GetOrAdd的行为,如果同时执行多个查询,
reader.GetOrdinal(“MyFieldName”)
可能会执行多次,不是确切地说是一次,但出于所有意图和目的,它可以被视为一次。

我回滚了上一次编辑,因为OP的问题是询问两个语句之间的功能差异-这个答案突出了处理空值时的差异,编辑显示了如何检查空值,不知道这与OP的问题有什么关系。好吧,在第一种情况下,最后一分钟的拆箱肯定会涉及。但是你确定在第二种情况下,在这个过程中没有类似的事情发生吗?可能与这里的元评论重复?你想回答这个问题吗?
//Well, we want to avoid the null exception issue entirely.
//Let's check for null first, before we try to use the value.

if( !dataReader.IsDBNull(dataReader.GetOrdinal("MyFieldName")))
{
//Store my data or use the value
string mystring=dataReader.GetString(dataReader.GetOrdinal("MyFieldName"));
}
static readonly ConcurrentDictionary<string, int> OrdinalMap = 
            new ConcurrentDictionary<string, int>();
reader.GetString(OrdinalMap.GetOrAdd("MyFieldName", reader.GetOrdinal))