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

时间:2015-06-04 14:57:45

标签: c# connection

它表示错误连接未关闭。 Connection的当前状态是打开的。 请帮忙解释一下代码。

  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);
        }

}

2 个答案:

答案 0 :(得分:0)

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();
    }
}

答案 1 :(得分:0)

您应该使用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注入攻击。由于您可能只希望返回一个值,因此应在查询中指定列的名称,并使用ExecuteScalar而不是阅读器和while循环。另一种方法是使用CommandBehavior.SingleRow作为命令的参数,它告诉命令只返回单行结果。

此处也存在跨线程问题,您可以使用一些调用来解决它。

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;

另一件需要注意的事情是为控件提供有意义的名称。 很多更容易调试或理解名为cbx_PlanType而非combobox1tbx_PlanAmount而不是textbox5的控件。