【问题标题】:Casting SqlDataReaders转换 SqlDataReaders
【发布时间】:2008-12-29 19:57:30
【问题描述】:

reader.GetInt32(0)代替(int)reader[0]有什么好处?我确信这样的铸造功能的存在是有原因的,但除了自己避免铸造在美学上更令人愉悦之外,我不确定这些原因是什么。

【问题讨论】:

  • 你能反映 reader.Get(index) 函数的源代码吗?我不认为他们在做演员,而是在内部做一个 Convert.ToInt32 。过去我在铸造方面遇到了问题,尽管它可能会稍微快一些。 See this question too。 DBNulls 可能会导致问题,所以基本上不要施放..
  • @nawal:没必要,因为 MS 共享了 the source code。而且两者的来源大相径庭,但我目前没有时间去探究原因。

标签: c# .net sql sqldatareader


【解决方案1】:

在代码中......

        void OneWay()
        {
            System.Data.SqlClient.SqlDataReader reader = null;
            int i = reader.GetInt32(0);
        }

        void OtherWay()
        {
            System.Data.SqlClient.SqlDataReader reader = null;
            int i = (int)reader[0];
        }

在伊利诺伊

.method private hidebysig instance void OneWay() cil managed
{
    .maxstack 2
    .locals init (
        [0] class [System.Data]System.Data.SqlClient.SqlDataReader reader,
        [1] int32 i)
    L_0000: nop 
    L_0001: ldnull 
    L_0002: stloc.0 
    L_0003: ldloc.0 
    L_0004: ldc.i4.0 
    L_0005: callvirt instance int32 [System.Data]System.Data.Common.DbDataReader::GetInt32(int32)
    L_000a: stloc.1 
    L_000b: ret 
}


.method private hidebysig instance void OtherWay() cil managed
{
    .maxstack 2
    .locals init (
        [0] class [System.Data]System.Data.SqlClient.SqlDataReader reader,
        [1] int32 i)
    L_0000: nop 
    L_0001: ldnull 
    L_0002: stloc.0 
    L_0003: ldloc.0 
    L_0004: ldc.i4.0 
    L_0005: callvirt instance object [System.Data]System.Data.Common.DbDataReader::get_Item(int32)
    L_000a: unbox.any int32
    L_000f: stloc.1 
    L_0010: ret 
}

所以,IL 是不同的,但我怀疑它们之间是否存在任何明显的差异。也许在一百万次迭代之后你会看到差异,但不太可能。

【讨论】:

  • 那个 unbox.any 对我来说很突出,但你可能是对的:upvote。
  • 哦:我也很好奇代码的结果,如果查询在该列中有一个 double 而不是 int。
  • unbox 可能是导致 reader[0] 语法返回一个装箱的整数(作为对象),我猜这就是它的症结......以“一种方式”调用 DbDataReader: :GetInt32() 返回一个 Int32,因此不会发生装箱/拆箱...谢谢!
  • 获取 SqlDataReader.GetInt32 和 get_Item(int32) 方法的 IL 以查看差异可能是值得的。我想必须在某个地方进行选角。
【解决方案2】:

前者也可以接受列名作为字符串而不是索引,并尝试将列值转换为 int。后者只接受索引,不会进行强制转换。

【讨论】:

    【解决方案3】:

    reader[0] 返回一个 System.Object,(int)reader[0] 实际上是在进行从 Object 到 Int32 的转换。

    如果您调用 GetXXX(0) 方法,则不会执行任何转换。因此,从流中检索到的数据必须已经是方法指定的类型。

    如果检索到的数据类型不匹配或列有 DBNull,则抛出 InvalidCastException。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-22
      • 2015-08-04
      • 1970-01-01
      相关资源
      最近更新 更多