连接未关闭。连接的当前状态是打开的

Connection was not closed. Connection's current state is open

报错连接未关闭。连接的当前状态是打开的。 请帮忙出代码。

  private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\vicky\Desktop\Gym management system\Fitness_club\vicky.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");
        try
        {
            con.Open();

            SqlCommand cmd = new SqlCommand("Select * FROM [plan] where plantype='" + comboBox1.Text + "'", con);

            SqlDataReader dr = cmd.ExecuteReader();

            while (dr.Read())
            {
                string amount = dr.GetString(1);
                textBox5.Text = amount;

            }
            con.Close();
        }

        catch(Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\vicky\Desktop\Gym management system\Fitness_club\vicky.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");
    try
    {
        con.Open();

        SqlCommand cmd = new SqlCommand("Select * FROM [plan] where plantype='" + comboBox1.Text + "'", con);

        SqlDataReader dr = cmd.ExecuteReader();

        while (dr.Read())
        {
            string amount = dr.GetString(1);
            textBox5.Text = amount;

        }
        // check if connection is open
        if (con.State == 1)
            con.Close();
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    finally
    {
        // check if connection is open
        if (con.State == 1)
            con.Close();
    }
}

您应该使用 using 块来帮助管理您的对象。

    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        string connStr = @"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\vicky\Desktop\Gym management system\Fitness_club\vicky.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";
        string cmdText = "Select * FROM [plan] where plantype=@planType";

        using (SqlConnection con = new SqlConnection(connStr))
        using (SqlCommand cmd = con.CreateCommand())
        {
            con.Open();
            cmd.CommandText = cmdText;
            cmd.Parameters.AddWithValue("@planType", comboBox1.Text);

            var reader = cmd.ExecuteReader(CommandBehavior.SingleRow);

            if (reader.Read())
            {
                string amount = reader.GetString(1);
                textbox5.Text = amount;
            }
        }
    }

还要注意使用参数化查询来避免 SQL 注入攻击。由于您可能只期望一个值被 returned,因此您应该在查询中指定列的名称并使用 ExecuteScalar 而不是 reader 和 while环形。另一种选择是使用 CommandBehavior.SingleRow 作为命令的参数,它告诉命令仅 return 单行结果。

你这里也有跨线程的问题,你可以通过一些调用来解决。

string amount = string.Empty;
if (reader.Read())
{
    amount = reader.GetString(1);
}
if (this.InvokeRequired)
    this.Invoke((MethodInvoker) delegate { textbox5.Text = amount; });
else
    textbox5.Text = amount;

另一件需要注意的事情是给你的控件起有意义的名字。 很多combobox1 更容易调试或理解名为 cbx_PlanType 的控件,或者 tbx_PlanAmount 而不是 textbox5.