2

データベースからデータを入力しようとしていますが、フォームが読み込まれたときとクリックdataGridViewされたときにデータを取得する必要があります..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おり、実行時に正しく動作しますが、データベースから行を削除すると問題が発生します (クリックしてクエリを使用し、展示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;
        }
    }
}

私はここで2つのことをしました:

  1. オブジェクトは、SqlConnectionクラス レベルではなく、メソッド内で作成されます。つまり、このメソッド以外は何も使用しません。(そのため、この方法以外はそれを壊すことはできません。)
  2. いくつかの使い捨てオブジェクトをusingステートメントでラップしました。これは、 を実装するものを扱うときのベスト プラクティスIDisposableです。
于 2013-10-03T13:40:13.963 に答える