与此命令关联的datareader已打开,必须先关闭

时间:2017-04-16 21:00:53

标签: c#

我有一个tablelayoutpanel,其中包含一个带文章名称的组合框和两个文本框,一个用于数量,另一个用于显示文章的最终价格,我想计算最终价格(价格*数量),但我得到的只是一个例外“与此命令关联的datareader已经打开,必须先关闭“但关闭所有读者:/

private void txtQ2_TextChanged(object sender, EventArgs e)
    {
        if (sqlCon.State == ConnectionState.Closed)
            sqlCon.Open();
        try {
            int q = tableLayoutPanel1.GetRow((TextBox)sender);
            ComboBox q1 = (ComboBox)tableLayoutPanel1.GetControlFromPosition(0, q);
            String NameArt = q1.Text;
            SqlCommand cmd2 = new SqlCommand("select PriceArticle from tbl_article where NameArticle='" + NameArt + "'", sqlCon);
            SqlDataReader dr1 = cmd2.ExecuteReader();
            if(dr1.Read())
            {
                int x = tableLayoutPanel1.GetRow(q1);
                TextBox y1 = (TextBox)tableLayoutPanel1.GetControlFromPosition(1, x);
                int z;
                bool parseOK1 = Int32.TryParse(y1.Text, out z);
                String a = dr1["PriceArticle"].ToString();
                int j;
                bool parseOK2 = Int32.TryParse(a, out j);
                int w = j * z;
                TextBox y2 = (TextBox)tableLayoutPanel1.GetControlFromPosition(2, x);
                y2.Text = w.ToString();
            }
            dr1.Close();
        }
        catch(Exception ex)
        {
            MessageBox.Show(ex.Message, "Error");
        }
    }

1 个答案:

答案 0 :(得分:0)

如错误所示:另一个操作仍处于打开状态。无论最后一个查询是什么:你没有干净地关闭它。请注意,DbCommandDbDataReader对象为IDisposable,因此您应该using。对于问题中的代码:

using(var cmd2 = new SqlCommand("select PriceArticle from tbl_article where NameArticle='" + NameArt + "'", sqlCon))
using(var dr1 = cmd2.ExecuteReader())
{
    // the rest of the code
}

几乎不用说,你永远不应该将输入连接到SQL,并且你的SQL对SQL注入非常开放。请切换到参数或工具,以帮助您像“小巧”一样正确。例如:

// via "dapper"
var article = sqlCon.QuerySingleOrDefault<string>(
    "select PriceArticle from tbl_article where NameArticle=@NameArt",
    new { NameArt });
if(article != null)
{
    ...
}