.NET SqlDataReader Item []与GetString(GetOrdinal())?

时间:2011-05-16 16:05:49

标签: .net

使用SqlDataReader类,如果有的话,它们之间的功能差异是什么:

(string) dataReader["MyFieldName"];

dataReader.GetString(dataReader.GetOrdinal("MyFieldName"));

5 个答案:

答案 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")可能会执行多次,而不是完全一次但是出于所有目的和目的,它可以被视为一次。