使用SqlDataReader
类,如果有的话,它们之间的功能差异是什么:
(string) dataReader["MyFieldName"];
和
dataReader.GetString(dataReader.GetOrdinal("MyFieldName"));
答案 0 :(得分:14)
除了抛出问题,对于单一呼叫,没有。索引器将调用DbDataReader.GetOrdinal
,然后调用相应的Get
方法来获取值(请注意,使用序数调用Get
方法比使用方法更快具有字段名称的索引器。)
然而,这将导致每次查找序数。如果您以只进,只读方式(完全 DbDataReader
实例的意图)来迭代许多记录,那么您可以减少开销这个查找只需一次。
你可以这样做:
// 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());
答案 1 :(得分:3)
处理空值时:
// 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"));
答案 2 :(得分:2)
在第一种情况下,您正在进行渲染,尤其是对于值类型(涉及拆箱)而言。就个人而言,我总是使用第二个,这就是我建议你的。
答案 3 :(得分:1)
//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"));
}
意外发现是一种很棒的发现方法。
答案 4 :(得分:0)
作为casperOne答案的替代方案,在应用程序的整个生命周期内减少序数查找很容易。它也可以在不需要手动维护变量来记录每个索引的情况下完成。
以下代码要求每个类有一个查询,如果要在一个类中处理多个,则很容易实现。
从字段开始:
static readonly ConcurrentDictionary<string, int> OrdinalMap =
new ConcurrentDictionary<string, int>();
然后更新您的访问代码,类似于:
reader.GetString(OrdinalMap.GetOrAdd("MyFieldName", reader.GetOrdinal))
现在你有了一个线程安全的O(1)查找序列,而不需要维护任何手动的变量映射或const用法,如果你改变查询打破世界。并不仅仅是因为GetOrAdd的行为而且由于GetOrAdd的行为而导致的清晰度,如果您同时执行多个查询,reader.GetOrdinal("MyFieldName")
可能会执行多次,而不是完全一次但是出于所有目的和目的,它可以被视为一次。