【问题标题】:DataReader[i] vs DataReader.GetValue(i) vs DataReader.GetString(i)DataReader[i] vs DataReader.GetValue(i) vs DataReader.GetString(i)
【发布时间】:2012-01-16 06:14:45
【问题描述】:

dataReader[i]

逻辑上等价于

dataReader.GetValue(i)

它们是一样的吗?它们不同吗?有没有一种情况适合另一种?

documented differently:

  • 获取位于指定索引处的列
  • 返回指定字段的值。

但是当我使用它们时,它们都会返回字段的值。 “获取列”是什么意思? “返回一个字段的值”是什么意思?


奖金闲聊

当我打电话时:

reader[i];
reader.GetValue(i);
reader.GetString(i);

我每次都会收到String

【问题讨论】:

    标签: .net ado.net datareader


    【解决方案1】:

    最终这取决于您所指的System.Data.IDataReader 的特定实现,但我们假设您的意思是System.Data.SqlClient.SqlDataReader

    在这种情况下,reader[i]reader.GetValue(i)完全相同做同样的事情。事实上,reader[i] 内部调用了reader.GetValue(i)。 (您可以通过使用类似ILSpy 的工具反汇编代码来看到这一点。)。这两个成员都返回当前行第i列的值,并且无论值的类型如何都会成功返回(返回类型为object)。这两个成员的文档有点误导,可以用更好的方式措辞。您可以在任何您喜欢的地方使用这些成员中的任何一个,只需选择您认为阅读效果更好的那个即可。

    reader.GetString(i) 专门设计用于将当前行的第 i 列中包含的值作为 string 返回。如果该列中的值不是string,则会抛出InvalidCastException。当您确定值是 string 并且 string 是您要使用的类型时,请使用此方法。这将使您的代码更加简洁,因为您不必执行强制转换。

    在您的具体情况下,当前行的第 i 列中的值必须是 string 类型,这就是所有三个成员的返回值相同的原因。

    如果编写正确,System.Data.IDataReader 的其他实现应该以相同的方式运行。

    【讨论】:

    • 存在可怕的边缘情况,GetValue 返回byte,但GetInt32 无法将字节转换为 Int32
    • 这很难说(特别是因为反汇编代码很难理解),但看起来列中的值必须已经是所需的类型,否则 InvalidCastException (这本身有点误导)将被抛出。我会编辑答案。
    • 确实,GetInt32 (msdn.microsoft.com/en-us/library/…) 的文档指出“不执行任何转换;因此,检索到的数据必须已经是 32 位有符号整数。”其他 GetXXX 方法也有类似记录。
    • @Ian, @Adam:这与(取消)拳击有关;与SqlDataReaderIDataReader 等本身没有直接关系。通常,装箱的值只能拆箱为它们的确切类型。例如,object o = (byte)42; int i = (int)o; 将失败并出现完全相同的错误,即使未装箱的 (byte)42 可以很高兴地转换为 int
    猜你喜欢
    • 2011-10-15
    • 2011-07-27
    • 1970-01-01
    • 1970-01-01
    • 2017-02-15
    • 2023-04-10
    • 2011-04-25
    相关资源
    最近更新 更多