【问题标题】:System.InvalidOperationException: 'Connection was not closed' [duplicate]System.InvalidOperationException:“连接未关闭”[重复]
【发布时间】:2018-06-06 08:52:49
【问题描述】:

我正在使用 C# Form 和 SQL Server。登录时遇到问题。

"System.InvalidOperationException: '连接未关闭'。

我无法解决这个问题。我想我添加了很多“con.Open()”。但我尝试了很多方法,但我仍然接受这个错误。猜猜,我又删了一个开关,是真的吗?

private void buttonLogin_Click(object sender, EventArgs e)
{
    con.Open();

    if (String.IsNullOrEmpty(textBoxUserName.Text))
    {
        MessageBox.Show("Username can't be empty");
        textBoxUserName.Focus();
        con.Close();
    }
    if (String.IsNullOrEmpty(textBoxPassword.Text))
    {
        MessageBox.Show("Password can't be empty");
        textBoxPassword.Focus();
        con.Close();
    }

    else
    {
        con.Open();
        SqlCommand SelectCommand = new SqlCommand("SELECT * FROM Users WHERE  username ='" + textBoxUserName.Text.Trim() + "' and password= '" + textBoxPassword.Text.Trim() + "'");
        SqlDataReader myReader;
        myReader = SelectCommand.ExecuteReader();
        int count = 0;
        string userRole = string.Empty;
        while (myReader.Read())
        {
            count = count + 1;
            userRole = myReader["userrank"].ToString();
        }

        if (count == 1)
        {

            if (userRole =="admin" )
            {
                Form1 form = new Form1();
                this.Hide();
                form.Show();
                con.Close();
            }
            else
            {
                UI ui = new UI();
                this.Hide();
                ui.Show();
                con.Close();
            }
            myReader.Close();
        }
        else
        {
            MessageBox.Show("Check your username or password");
            con.Close();
        }           
    }       
}

【问题讨论】:

  • 解决方案:不要重复使用你的连接,但总是在你使用它的地方打开和关闭它(在方法中),最好使用using-statement 来确保它总是被处理/关闭.
  • 您应该使用using,并且您应该在尽可能小的范围内创建(并处置)一个连接,而不是重用con 对象。 SqlConnection 实例只是句柄,而不是物理连接,您可以打开和关闭它们几乎没有任何资源成本。重用它们只会给你带来麻烦——首先,你如何处理断开的连接? (答案是:非常尴尬,如果你只有一个实例。)
  • 我看不懂Form1 form = new Form1();UI ui = new UI(); 行。
  • 你被这么多的打开/关闭弄糊涂了。为什么在进行正常验证时还要费心打开?始终使用using,以便您始终确定。
  • @SeM 如果管理员要登录,请通过 Form1 或用户要登录 UI。

标签: c# sql sql-server winforms


【解决方案1】:

您可以在打开连接之前检查状态 - 因为打开打开的连接会失败。

if(con.State == ConnectionState.Closed)
{
    con.Open();
}

旁注:最佳做法是

string command = "SELECT * FROM Users WHERE  username = @username and password = @password";
using (SqlConnection con = new SqlConnection(ConnectionString))
{
    con.Open();
    using (SqlCommand cmd = new SqlCommand(command, con))
    {
        cmd.Parameters.Add("@username", SqlDbType.VarChar).Value = textBoxUserName.Text.Trim();
        cmd.Parameters.Add("@password", SqlDbType.VarChar).Value = textBoxPassword.Text.Trim();
        using (SqlDataReader reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                count = count + 1;
                userRole = myReader["userrank"].ToString();
            }
        }
    }
}
  • 使用using,您不必关心状态、关闭和处理连接
  • 使用参数避免注入攻击

【讨论】:

    【解决方案2】:

    使用 using 构造。

    using (con)
    {
      //do your work
    }
    

    这将在成功和异常的情况下自动处理连接

    【讨论】:

    • con 也应该在使用中声明以正确处理using (SqlConnection con = new SqlConnection(ConnectionString))
    【解决方案3】:

    您似乎有一些多余的代码。无需在开始时打开连接,稍后再次关闭,无需使用连接。

    如果它遇到您的第一个 if 语句,它似乎可能会遇到您的 else 语句。

    我认为下面的代码可以解决您的问题,即可以通过点击第一个 if 语句来关闭 con 对象。当然,假设您已经在全局范围内实例化了 con 对象。

    private void buttonLogin_Click(object sender, EventArgs e)
    {
        if (String.IsNullOrEmpty(textBoxUserName.Text))
        {
            MessageBox.Show("Username can't be empty");
            textBoxUserName.Focus();
        }
        else if (String.IsNullOrEmpty(textBoxPassword.Text))
        {
            MessageBox.Show("Password can't be empty");
            textBoxPassword.Focus();
        }
        else
        {
            using (SqlConnection con = new SqlConnection(ConnectionString))
            {
                SqlCommand SelectCommand = new SqlCommand("SELECT * FROM Users WHERE  
                username ='" + textBoxUserName.Text.Trim() + "' and password= '" + textBoxPassword.Text.Trim() + "'");
                SqlDataReader myReader;
                myReader = SelectCommand.ExecuteReader();
                int count = 0;
                string userRole = string.Empty;
                while (myReader.Read())
                {
                    count = count + 1;
                    userRole = myReader["userrank"].ToString();
                }
    
                if (count == 1)
                {
    
                    if (userRole =="admin" )
                    {
                        Form1 form = new Form1();
                        this.Hide();
                        form.Show();
                        con.Close();
                    }
                    else
                    {
                        UI ui = new UI();
                        this.Hide();
                        ui.Show();
                        con.Close();
                    }
                    myReader.Close();
                }
                else
                {
                    MessageBox.Show("Check your username or password");
                    con.Close();
                }           
            } 
        }      
    }
    

    【讨论】:

    • 我试了一下,但现在我接受了这个:“System.InvalidOperationException: 'Connection dont started”
    • 我在@fubo 的启发下编辑了关于“使用”声明的答案。您必须将“con”对象的全局实例化移动到“using”行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    相关资源
    最近更新 更多