C# 需要关闭与命令关联的SqlDataReader才能成功登录
每次尝试使用正确的凭据登录时,我都会收到以下错误消息: 已存在与此命令关联的打开的DataReader,必须先关闭该命令 请有人能剖析这段代码,这样我才能最终进入下一阶段,谢谢大家C# 需要关闭与命令关联的SqlDataReader才能成功登录,c#,database,visual-studio,sqldatareader,C#,Database,Visual Studio,Sqldatareader,每次尝试使用正确的凭据登录时,我都会收到以下错误消息: 已存在与此命令关联的打开的DataReader,必须先关闭该命令 请有人能剖析这段代码,这样我才能最终进入下一阶段,谢谢大家 // Login Function for Manual Login public void ent() { try { SqlConnection con = new SqlConnection(cc.connectDB()); con.Open();
// Login Function for Manual Login
public void ent()
{
try
{
SqlConnection con = new SqlConnection(cc.connectDB());
con.Open();
SqlCommand cmd = new SqlCommand("delete from log", con);
cmd.ExecuteNonQuery();
SqlCommand cmd1 = new SqlCommand("select * from Login where username='" + username.Text + "' and password='" + password.Text + "'", con);
cmd1.ExecuteNonQuery();
SqlDataReader c = cmd1.ExecuteReader();
if (c.Read() == true)
{
SqlCommand cmd2 = new SqlCommand("select typeid from Login where username='" + username.Text + "' and password='" + password.Text + "'", con);
Int32 count = (Int32)cmd2.ExecuteScalar();
if (count == 1)
{
SqlCommand cmd3 = new SqlCommand("insert into log values ('" + 1 + "')", con);
cmd3.ExecuteNonQuery();
}
else
if (count == 2)
{
SqlCommand cmd3 = new SqlCommand("insert into log values ('" + 2 + "')", con);
cmd3.ExecuteNonQuery();
}
Menu shw = new Menu();
shw.Show();
this.Hide();
}
else
{
MessageBox.Show("Login failed");
}
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
}
我正在连接一个已完全启动并运行的SQL Express服务器,但我似乎无法找到一种方法来关闭读卡器,而不会导致不必要的错误。问题可能源于此,即您不应该调用无关的
cmd1.ExecuteNonQuery()调用cmd1.ExecuteReader()之前的代码>
:
编辑
在哪里?像这样。而且,您还需要修改您的查询。请注意,为了防止大量嵌套,您可以:
var someMessageToShowToUser = "";
try
{
using (var con = new SqlConnection(cc.connectDB()))
using (var cmd = new SqlCommand("delete from log", con))
using (var cmd1 = new SqlCommand(
"select * from Login where username=@UserName and password=@Password", con))
{
con.Open();
cmd.ExecuteNonQuery();
cmd1.Parameters.AddWithValue("@UserName", username.Text);
cmd1.Parameters.AddWithValue("@Password", password.Text);
// cmd1.ExecuteNonQuery(); -> Delete this line.
using (var c = cmd1.ExecuteReader())
{
if (c.Read() == true)
{
using (var cmd2 = new SqlCommand("Parameterize me too")
{
var count = (Int32) cmd2.ExecuteScalar();
if (count == 1)
{
using (var cmd3 = new SqlCommand("insert into log values (@AnotherParam)", con))
{
cmd3.ExecuteNonQuery();
}
}
else if (count == 2)
{
using (var cmd3 = new SqlCommand("insert into log values (@AnotherParam)", con))
{
cmd3.ExecuteNonQuery();
}
}
Menu shw = new Menu();
shw.Show();
this.Hide();
}
}
else
{
someMessageToShowToUser = "Login failed";
}
}
}
}
catch (Exception ee)
{
someMessageToShowToUser = ee.Message;
}
MessageBox.Show(someMessageToShowToUser);
我想另一点是,在打开数据库连接时显示消息框(等待用户单击按钮)不是一个好主意。理想情况下,您需要将数据访问代码与演示文稿代码分离(可能还需要进一步分离)。在同一个表(dbo.LOGIN)上执行select两次,而无需在第二次执行前关闭读卡器
而不是跟随这一行
SqlCommand cmd2 = new SqlCommand("select typeid from Login where username='" + username.Text + "' and password='" + password.Text + "'", con);
Int32 count = (Int32)cmd2.ExecuteScalar();
您可以将typeid读取为
INT32 count = Convert.ToInt32(c["typeid"].ToString());
另外,建议您处理连接、命令和读取器对象,否则您迟早会遇到一些错误
比如说
using(SqlConnection con = new SqlConnection(cc.connectDB())
{
con.Open();
using(SqlCommand cmd = new SqlCommand("delete from log", con))
{
cmd.ExecuteNonQuery();
}
using(SqlCommand cmd1 = new SqlCommand("select * from Login where username='" + username.Text + "' and password='" + password.Text + "'", con))
{
//You don't need this
//cmd1.ExecuteNonQuery();
using(SqlDataReader c = cmd1.ExecuteReader())
{
//You don't need these lines - this is probably the line of error
//SqlCommand cmd2 = new SqlCommand("select typeid from Login where username='" + username.Text + "' and password='" + password.Text + "'", con);
//Int32 count = (Int32)cmd2.ExecuteScalar();
INT32 count = Convert.ToInt32(c["typeid"].ToString());
//other sruffs
}
}
}
使用c.Dispose();在最后一块。同意@Anurag Jain。您必须使用finally block和dispose数据读取器。感谢您的快速响应,我将在何处插入建议的代码?由于每次将“dispose”命令作为“finally”命令放置在代码中时都会出现错误,我可以用什么方式建立“dispose”命令?您可以使用block将连接对象包围起来。查看更新后的答案。如果您已在finally block中处理了对象,那么就可以了(您不需要使用block)。我使用MARS最终解决了这个问题,完成了一次完整的处理!
INT32 count = Convert.ToInt32(c["typeid"].ToString());
using(SqlConnection con = new SqlConnection(cc.connectDB())
{
con.Open();
using(SqlCommand cmd = new SqlCommand("delete from log", con))
{
cmd.ExecuteNonQuery();
}
using(SqlCommand cmd1 = new SqlCommand("select * from Login where username='" + username.Text + "' and password='" + password.Text + "'", con))
{
//You don't need this
//cmd1.ExecuteNonQuery();
using(SqlDataReader c = cmd1.ExecuteReader())
{
//You don't need these lines - this is probably the line of error
//SqlCommand cmd2 = new SqlCommand("select typeid from Login where username='" + username.Text + "' and password='" + password.Text + "'", con);
//Int32 count = (Int32)cmd2.ExecuteScalar();
INT32 count = Convert.ToInt32(c["typeid"].ToString());
//other sruffs
}
}
}