为什么要使用SqlDataReader的GetOrdinal()方法

时间:2009-07-03 13:30:28

标签: sqldatareader

使用以下语法从SqlDataReader读取值之间的区别是什么:

Dim reader As SqlClient.SqlDataReader
reader("value").ToString()

OR

Dim reader As SqlClient.SqlDataReader
reader.GetString(reader.GetOrdinal("value"))

4 个答案:

答案 0 :(得分:11)

我认为使用GetOrdinal()的原因是您可以缓存结果并多次重复使用它以获得性能。

E.g。

Dim reader As SqlClient.SqlDataReader
int valueOrdinal = reader.GetOrdinal("value");
while ( ... )
{
    var value = reader.GetString(valueOrdinal);
}

答案 1 :(得分:6)

GetOrdinal首先执行区分大小写的查找。如果失败,则进行第二次不区分大小写的搜索。 GetOrdinal是假名宽度不敏感的。因为基于序数的查找比命名查找更有效,所以在循环中调用GetOrdinal是低效的。通过调用GetOrdinal一次并将结果分配给整数变量以便在循环中使用来节省时间。

来源:http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getordinal.aspx

答案 2 :(得分:1)

我只想补充一点,你所期望的记录数量的上下文起着重要的作用,因为如果你要返回一行,那么这两者之间的性能差异就不会很大。但是,如果要循环多行,那么使用类型化访问器可以提高性能,因为它已经过优化。因此,在这种情况下,如果您需要通过使用列名称获得最佳性能,则调用GetOrdinal一次,将其放入变量中,然后在循环中使用带序列的序列访问器。这将产生最佳性能。

如果您对性能差异感到好奇,请查看my blog post

答案 3 :(得分:0)

您的里程可能会有所不同,但是...

您要获取的行越多,您将看到的性能改进就越多。我喜欢在SELECT语句中使用列别名,例如

select
    physical_column_name as "MyFieldName"

并且已经编写了一种方法,应该是不言自明的,

public Dictionary<String, Int32> GetOrdinalsByName(DbDataReader reader)

所以,我的作业看起来像

    public void BindRow(DbDataReader dr)
    {
        TerminationDate = dr.GetDateTime(_columnOrdinals["TerminationDate"]);

字典执行接近O(1);因此,这是性能和可维护性之间的合理权衡。