如何在C#中正确读取SqlDataReader中的数据?

时间:2015-07-31 09:09:45

标签: c# sql

我们假设我们有一个开放的SqlConnection并执行一个任意查询,从而产生一个包含一列 Foo 的表,其中包含整数。

要读取这些整数,我注意到有两种方法可以访问列中的值:

using (var reader = command.ExecuteReader())
{
    if (reader.HasRows)
    {
        while (reader.Read())
        {
            // access value directly either by column name or index
            int i = (int)reader["Foo"];
            int j = (int)reader[0];

            // access value by using GetOrdinal
            int k = reader.GetInt32(reader.GetOrdinal("Foo"));
        }
    }
}

两种方法当然都会产生相同的值。我正在使用第一种方法,因为我似乎更容易使用列名直接访问值而不是使用它来获取其索引,然后使用该索引来访问该值。

但我对这个问题很陌生,那么这里的最佳做法是什么?目前的惯例?绩效方面的差异?

4 个答案:

答案 0 :(得分:1)

所有方法都是正确的,但reader["Foo"]reader[0]正在使用定义的重载索引器。它总是容易/可读,并建议在索引器中使用列名而不是使用索引。不确定它们之间的性能差异。

        int i = (int)reader["Foo"];
        int j = (int)reader[0];

答案 1 :(得分:1)

类似的东西:

using (var reader = command.ExecuteReader()) {
  // if (reader.HasRows) is redundant

  // do not repeat this in the loop
  int k_index = reader.GetOrdinal("Foo");

  while (reader.Read()) { 
    // reader["Foo"] is not necessary int; 
    // better practice is to convert since reader["Foo"] could be, say, Oracle Number
    int i = Convert.ToInt32(reader["Foo"]);
    // usually, reader[123] (instead of reader["MyField"]) syntax looks ugly, but
    // it may happen that, say, "id" is always the first field in the query - 
    // so reader[0] syntax is reasonable  
    int j = Convert.ToInt32(reader[0]);
    // what if reader[index] is declared as Int64 but contains Int32 values - convert
    int k = Convert.ToInt32(reader[k_index]);
  }
}

答案 2 :(得分:1)

使用反射器,您可以在内部看到索引器[]与调用方法

相同
public override object this[int i]
{
    get
    {
        return this.GetValue(i);
    }
}
public override object this[string name]
{
    get
    {
        return this.GetValue(this.GetOrdinal(name));
    }
}

所以实际差异是。如果您知道位置并关心性能,请使用方法的int版本。

 int j = (int)reader[0];//direct array access for some column
 int j = reader.GetInt32(0);

如果您不知道该位置或更喜欢可读性,请使用字符串版本

 //must first goto hash table and waist time looking for column index
 int j = (int)reader["price"]; //but at least we know the meaning of the column
 int j = reader.GetInt32(reader.GetOrdinal("price"));
 int j = (int)reader.GetValue(reader.GetOrdinal("price"));

并最终确定GetInt32GetValue之间的差异只是GetInt32为您进行类型验证和投射,因此如果您知道数据类型会让您的生活更轻松。

PS。通过名称查找列索引的性能损失通常是可以忽略的..但是......不应该被忽略,我有一个项目,其中GetOrdinal是最被称为函数的函数之一数十万次总结到几秒钟,我可以通过使用整数来避免,现在我遇到了瓶颈,我无法重写应用程序。

答案 3 :(得分:0)

您将经常使用SqlDataReader,因此请尽可能简化,指定列名称:

int i = (int)reader["Foo"];