C# System.InvalidOperationException:&x27;连接未关闭';
我正在使用C#Form和SQL Server。我登录时遇到问题 “System.InvalidOperationException:'连接未关闭' 我无法解决这个问题。我想我添加了很多“C# System.InvalidOperationException:&x27;连接未关闭';,c#,sql,sql-server,winforms,C#,Sql,Sql Server,Winforms,我正在使用C#Form和SQL Server。我登录时遇到问题 “System.InvalidOperationException:'连接未关闭' 我无法解决这个问题。我想我添加了很多“con.Open()”。但我尝试了很多方法,但仍然犯了这个错误。我想,我又删除了一个Open和close,是真的吗 private void buttonLogin_Click(object sender, EventArgs e) { con.Open(); if (String.IsNull
con.Open()
”。但我尝试了很多方法,但仍然犯了这个错误。我想,我又删除了一个Open和close,是真的吗
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();
}
}
}
您可以在打开连接之前检查状态,因为打开打开的连接将失败
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();
}
}
}
}
- 使用
时,您不必关心状态、关闭和处理连接
- 使用参数避免注入攻击
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();
}
}
}
}
- 使用
时,您不必关心状态、关闭和处理连接
- 使用参数避免注入攻击
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();
}
}
}
}
看起来你有一些多余的代码。没有必要在开始时打开连接,然后再关闭它,而不必使用连接 而且,如果它击中你的第一个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();
}
}
}
}
使用构造
using (con)
{
//do your work
}
这将在成功和异常情况下自动处理连接使用construct
using (con)
{
//do your work
}
这将在成功和出现异常时自动处理连接解决方案:不要重复使用连接,而是始终在使用连接的位置(在方法中)打开和关闭连接,最好使用
using
-语句以确保它始终被处理/关闭。您应该使用,并且应该创建(和处理)在尽可能小的范围内建立连接,而不是重用con
对象。SqlConnection
实例只是句柄,而不是物理连接,您可以在几乎没有任何资源成本的情况下打开和关闭它们。重用它们只会给您带来麻烦——首先,您如何处理断开的连接?(答案是:非常尴尬,如果你只有一个实例。)我不理解Form1 form=new Form1();
和UI=new UI()
行。你被这么多打开/关闭操作弄糊涂了。为什么在进行正常验证时还要麻烦打开呢?请始终使用使用,这样你才能始终确定。@如果管理员想要登录,请传递Form1或用户想要登录UI。解决方案:不要重复使用你的连接,而是始终在使用它的地方(在方法中)打开和关闭它,最好使用using
-语句来确保它始终被释放/关闭。您应该使用,并且应该创建(和释放)在尽可能小的范围内建立连接,而不是重用con
对象。SqlConnection
实例只是句柄,而不是物理连接,您可以在几乎没有任何资源成本的情况下打开和关闭它们。重用它们只会给您带来麻烦——首先,您如何处理断开的连接?(答案是:非常尴尬,如果你只有一个实例。)我不理解Form1 form=new Form1();
和UI=new UI()
行。你把自己弄糊涂了,有这么多打开/关闭的代码。为什么在进行正常验证时还要麻烦打开呢?始终使用使用,这样你就可以始终确定了。@SeM如果管理员想登录,请传递Form1或用户想要登录UI。我尝试过了,但现在我接受了这个命令:“System.InvalidOperationException:”连接未启动“我根据@fubo关于“使用”语句的灵感编辑了我的答案。你必须将“con”对象的全局实例化移到“using”行。我尝试了一下,但现在我接受了以下内容:“System.invalidoOperationException:‘Connection dont start’”我根据@fubo关于“使用”的灵感编辑了我的答案”语句。您必须将“con”对象的全局实例化移动到“using”行。con
还应在using中声明以正确处置using(SqlConnection con=new-SqlConnection(ConnectionString))
还应在using中声明以正确处置using(SqlConnection con=newsqlconnection(ConnectionString))