SqlDataReader问题

时间:2011-02-15 22:14:16

标签: c# ado.net sqldatareader datareader

将数据存储到SqlDataReader时出现问题。当我分配sdr变量时,在connection.close()的位置,sdr变量变空。为什么呢?

   string strConnection = ConfigurationManager.ConnectionStrings["dbconn"].ConnectionString;

   SqlDataReader sdr = null;

    using (SqlConnection connection = new SqlConnection(strConnection))
    {
        connection.Open();
        using (SqlCommand cmd = new SqlCommand("GetProducts", connection))
        {


            cmd.CommandType = System.Data.CommandType.StoredProcedure;

            sdr = cmd.ExecuteReader();


        }
        connection.Close();
    }

    return (sdr);

2 个答案:

答案 0 :(得分:3)

您需要在调用Read:

的循环中迭代读取器
while(sdr.Read())
{
   var someValue = sdr["SomeValue"]; //Where SomeValue is the column name you're expecting from the DB
}

所有ExecuteReader都会这样做,它是否会向您返回一个DataReader对象,但是您需要遍历返回的每一行并从中提取值。如果您想一次性完成所有操作,可以使用SqlDataAdapter:

var adapter = new SqlDataAdapter(command);
var table = new DataTable();
adapter.Fill(table);

答案 1 :(得分:3)

在迭代DataReader时,您需要一个开放且活动的连接。如果在返回数据读取器之前关闭它,它将无法工作。我通常做的就是将DataReader变成IEnumerable,如下所示:

public IEnumerable<IDataRecord> GetProductsFromDB()
{
    string strConnection = ConfigurationManager.ConnectionStrings["dbconn"].ConnectionString;

    using (SqlConnection connection = new SqlConnection(strConnection))
    using (SqlCommand cmd = new SqlCommand("GetProducts", connection))
    {
        cmd.CommandType = System.Data.CommandType.StoredProcedure;

        connection.Open();
        using (var sdr = cmd.ExecuteReader())
        {
            while (sdr.Read())
            {
                yield return sdr;
            }
        }    
    }
}

请注意,我也改变了一下顺序:等待尽可能长时间打开连接,然后在每个连接旁边放置连接和命令,以避免这么多嵌套。

这种模式为您编写数据访问代码的方式开辟了一个全新的世界,因为现在突然您的原始SQL查询和存储过程调用与linq-to-objects运算符一起工作。你可以这样做很酷:

foreach (var product in GetProductsFromDB()
           .Select(i => CreateProductFromDataRow(i))
           .Where(p => p.IsOnSale()) )
{
    // do something with products that are on sale
}