2

我正在尝试dataGridView用数据库中的数据填充 a,它必须在加载表单和refreshButton单击时获取数据。

这是代码:

public partial class PhoneBookMainWindow : Form
{
    static public string connString = "Server=(local); Database=PhoneBook; Trusted_Connection=TRUE";
    public SqlConnection connection = new SqlConnection(connString);
    private void btnRefreshPhoneBook_Click(object sender, EventArgs e)
    {
        SqlCommand command = new SqlCommand("SELECT ID, contactName, jobTitle, currentAddress, workAddress, workPhone, cellPhone FROM ContactsInformations", connection);
        try
        {
            SqlDataAdapter dataAdapter = new SqlDataAdapter();
            dataAdapter.SelectCommand = command;
            DataTable dataSet = new DataTable();
            dataAdapter.Fill(dataSet);
            BindingSource bindingSrc = new BindingSource();

            bindingSrc.DataSource = dataSet;
            dataGridView1.DataSource = bindingSrc;
            dataAdapter.Update(dataSet);
        }
        catch (Exception x)
        {
            MessageBox.Show(x.Message);
            throw;
        }

    }
}

Form loading我在&中使用相同的代码,btn clicking它们在执行中正常工作,但是当我从数据库中删除一行时出现问题(通过单击 a 使用查询delete btn然后单击refresh btn展览来到我面前。

4

1 回答 1

6

您似乎面临的问题是您有多个代码块共享同一个SqlConnection对象。抛开潜在的竞争条件不谈,这意味着他们中的任何一个都可能在另一个人使用该对象之前尝试处置该对象。

一旦处置,该对象就不再处于您可以使用它的状态。特别是在这种情况下,它不再有.ConnectionString集合。

本质上,这正在发生:

  • A类初始化连接
  • 方法 A1 使用连接
  • 方法 A1 完成连接并处理它
  • 方法 A2 尝试使用连接,但不能,因为它已被释放

创建SqlConnection对象并不是一个特别耗费资源的过程,因此最好将其范围限定在将要使用它的代码的本地范围内。像这样的东西:

using (SqlConnection connection = new SqlConnection(connString))
{
    using (SqlCommand command = new SqlCommand("SELECT ID, contactName, jobTitle, currentAddress, workAddress, workPhone, cellPhone FROM ContactsInformations", connection))
    {
        try
        {
            SqlDataAdapter dataAdapter = new SqlDataAdapter();
            dataAdapter.SelectCommand = command;
            DataTable dataSet = new DataTable();
            dataAdapter.Fill(dataSet);
            BindingSource bindingSrc = new BindingSource();

            bindingSrc.DataSource = dataSet;
            dataGridView1.DataSource = bindingSrc;
            dataAdapter.Update(dataSet);
        }
        catch (Exception x)
        {
            MessageBox.Show(x.Message);
            throw;
        }
    }
}

我在这里做了两件事:

  1. 对象是在方法内部创建的SqlConnection,而不是在类级别创建的。这意味着除了这个方法之外什么都不会使用它。(所以除了这个方法之外没有什么可以破坏它。)
  2. 我在using语句中包装了一些一次性对象,这是处理任何实现IDisposable.
于 2013-10-03T13:40:13.963 回答