我将数据从
Windows Forms表单插入到sql数据库中,如下所示:
public partial class Form1 : Form { sqlConnection c = new sqlConnection(); string q = "Trusted_Connection = true; "; public Form1() { InitializeComponent(); c.ConnectionString = q; MessageBox.Show("Connecting Database"); } private void button1_Click(object sender,EventArgs e) { string w = "insert into checkmultiuser(username) values (@username)"; sqlCommand cmd = new sqlCommand(w,c); cmd.Parameters.Add("@username",sqlDbType.VarChar); cmd.Parameters["@username"].Value = textBox1.Text; cmd.ExecuteReader(); }
但是,当我再次单击该按钮时,它会显示“已经有一个与此命令关联的打开的DataReader必须先关闭.”.
我该如何处理?
*更新:*我已更改按钮点击事件代码,如下所示:
private void button1_Click(object sender,EventArgs e) { **c.Open();** string w = "insert into checkmultiuser(username) values (@username)"; sqlCommand cmd = new sqlCommand(w,c); cmd.Parameters.Add("@username",sqlDbType.VarChar); cmd.Parameters["@username"].Value = textBox1.Text; //cmd.ExecuteNonQuery(); cmd.ExecuteReader(); **c.Close();** }
它的缺点是什么?一个是一次又一次,当点击按钮时,连接被打开和关闭.
解决方法
读者需要打开连接,因为您一次检索一个结果.您需要为插入,删除和更新执行
ExecuteNonQuery().您还需要在事后关闭连接.另一种方法是,如果计划进行多次插入,则将插入包装成循环.
有几种方法可以做到这一点.如果您计划一遍又一遍地重用相同的连接对象和命令对象,这种方法很有用:
public partial class Form1 : Form { sqlConnection _cn; sqlCommand _cmd; const string ConnString = "Enter your connection string here"; readonly string _insertQuery; const string UsernameParm = "@username"; public Form1() { InitializeComponent(); _cn = new sqlConnection(ConnString); _cmd = new sqlCommand(InsertQuery,_cn); _cmd.Parameters.Add(UsernameParm,sqlDbType.VarChar); _insertQuery = String.Format("INSERT INTO checkmultiuser(username) VALUES ({0})",UsernameParm); } private void button1_Click(object sender,EventArgs e) { _cmd.Parameters[UsernameParm].Value = textBox1.Text; try { _cn.Open(); _cmd.ExecuteNonQuery(); } catch (Exception ex) // probably best to catch specific exceptions { // handle it } finally { _cn.Close(); } } }
只需确保处理连接和命令对象(当表单关闭或对应用程序最有意义时).
使用块是一种更安全的替代方法,但它们每次都会处理该对象(尽管默认情况下连接使用连接池):
public partial class Form1 : Form { const string ConnString = "Enter your connection string here"; readonly string _insertQuery; const string UsernameParm = "@username"; public Form1() { InitializeComponent(); _insertQuery = String.Format("INSERT INTO checkmultiuser(username) VALUES ({0})",EventArgs e) { using (var cn = new sqlConnection(ConnString)) { using (var cmd = new sqlCommand(InsertQuery,cn)) { cmd.Parameters.Add(UsernameParm,sqlDbType.VarChar); cmd.Parameters[UsernameParm].Value = textBox1.Text; cn.Open(); cmd.ExecuteNonQuery(); } } } }
任何组合都可以.您可以设置一次连接,然后将命令对象包装在using块中.我知道有些人不是嵌套使用块的粉丝(因为在幕后它是尝试(最后尝试))).