【问题标题】:SqlDataReader problemsSqlDataReader 问题
【发布时间】:2011-02-15 22:14:16
【问题描述】:

将数据存储到 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);

【问题讨论】:

    标签: c# ado.net sqldatareader datareader


    【解决方案1】:

    您需要在调用 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);
    

    【讨论】:

    • 不能将值作为 SqlDataReader 返回吗?
    • @user:你可以这样做,但是你需要保持连接打开。一旦关闭连接,Reader 就无法继续从 DB 中读取...
    【解决方案2】:

    在遍历 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
    }
    

    【讨论】:

    • 很酷的图案,从未见过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多