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

22

使用以下语法从SqlDataReader中读取值有什么区别:

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

或者

Dim reader As SqlClient.SqlDataReader
reader.GetString(reader.GetOrdinal("value"))
4个回答

16

我认为使用GetOrdinal()的原因在于可以缓存该结果并在多次使用时提高性能。

例如:

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

1
有人知道在行循环中使用GetOrdinal(..)与实际从数据库检索数据相比的性能影响吗? - Juha Palomäki
4
我有一个针对 Web API 服务的性能测试,它从存储过程中读取大约30-40条记录(包含多个结果集),并返回大约8K大小的 Json。在此测试中,我将所有的 GetOrdinal() 替换为静态 int 常量,结果性能提高了2%……所以是否值得创建这种列名缓存呢?在大多数场景下,我认为不用。从数据库中读取数据和将数据序列化为 Json 在实际场景中会更影响性能,所以我认为当你已经优化了其他一切时,缓存序号将是最后要做的事情。 - Bogdan_Ch
我可能读错了,但我相信使用GetOrdinal也可以解析一行数据而不依赖于每个项的索引,因为结果可能并不总是按预期索引。使用GetOrdinal允许访问读取器的列值,而无需知道该值的索引位置。 - Anthony Tristan

8
GetOrdinal首先执行区分大小写的查找。如果失败,就进行第二次不区分大小写的搜索。GetOrdinal在假名宽度上是不敏感的。由于基于序号的查找比命名查找更有效率,在循环中调用GetOrdinal是低效的。通过调用GetOrdinal一次并将结果赋值给一个整数变量以在循环中使用来节省时间。
来源:http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getordinal.aspx

8
请将以下英文内容翻译成中文,仅返回翻译后的文本:从 http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getordinal.aspx 复制并粘贴原文即可。;-) - jpoh
4
为什么不直接链接整篇文章呢?他的评论缺少很多内容。 - Dave
8
通常不会直接链接整篇文章,因为它可能不会一直存在,而且需要浏览很多内容。你应该引用相关部分并加上链接。 - Chet

3
我想补充一点,期望返回多少记录在上下文中起着重要作用,因为如果你只返回单行,则这两种方式之间的性能差异不会很大。然而,如果您正在循环处理许多行,则使用类型化的访问器会更好地优化性能。因此,在这种情况下,如果您需要通过列名获取最佳性能,请调用GetOrdinal一次,将其放入变量中,然后在循环中使用具有列序号的类型访问器。这将产生最佳性能。
如果您对性能差异感到好奇,请查看我的博客文章

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); 因此,这是性能和可维护性之间的合理权衡。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接