20

レガシーアプリでADO.NET(.NET 1.1)を使用しています。DataAdapterに渡される前に接続が手動で開かれていない場合、DataAdapter.Fill()が接続を開いたり閉じたりすることを知っています。

私の質問:.Fill()が例外を引き起こした場合、接続も閉じますか?(SQL Serverに到達できないなどの理由で)。接続がリークしますか、それとも接続が閉じられていることを確認するための組み込みのFinally句がありますか?

コード例:

Dim cmd As New SqlCommand
Dim da As New SqlDataAdapter
Dim ds As New DataSet
cmd.Connection = New SqlConnection(strConnection)
cmd.CommandText = strSQL
da.SelectCommand = cmd
da.Fill(ds)
4

2 に答える 2

23

Fill()メソッドが呼び出される前に接続が開いている場合、いいえ、接続はDataAdapterによって閉じられません。

ただし、接続を明示的に開かず、代わりにDataAdapterでFill()コマンド内の接続を開いたり閉じたりすると、エラー時に接続が閉じられます。

これは、次のドキュメントを含む複数のドキュメントソースから暗示されている可能性があります。ADO.NETおよびSQLを使用したデータアクセス戦略

さらに、これは、エラーになるルーチンを記述してから接続の状態をチェックすることにより、コードで示すことができます。

Windowsフォームアプリからのこのコードはそれを証明します。最初のメッセージボックスには「開く」、2番目のメッセージボックスには「閉じる」と表示されます。

              string connString = "";
        private void Form1_Load(object sender, EventArgs e)
        {
            connString = Properties.Settings.Default.EventLoggingConnectionString;
            ExplicitlyOpenConnection();
            LetDataAdapterHandleIt();
        }

        private void ExplicitlyOpenConnection()
        {
            System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection(connString);
            System.Data.DataSet ds = new DataSet();
            System.Data.SqlClient.SqlDataAdapter ad = new System.Data.SqlClient.SqlDataAdapter("Select bogusdata from nonexistenttable", cn);

            cn.Open();
            try
            {
                ad.Fill(ds);
            }
            catch (Exception ex)
            {

            }

            MessageBox.Show(cn.State.ToString());
            cn.Close();
        }
        private void LetDataAdapterHandleIt()
        {
            System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection(connString);
            System.Data.DataSet ds = new DataSet();
            System.Data.SqlClient.SqlDataAdapter ad = new System.Data.SqlClient.SqlDataAdapter("Select bogusdata from nonexistenttable", cn);

            try
            {
                ad.Fill(ds);
            }
            catch (Exception ex)
            {

            }
            MessageBox.Show(cn.State.ToString());
        }
于 2010-03-18T19:46:41.813 に答える
1

接続は閉じません。この例は機能し、「ARealTable」のIDを出力します

            using (SqlConnection conn = new SqlConnection("Data Source=server;Initial Catalog=database;user id=sa; password=password;"))
            {
                conn.Open();

                try
                {
                    SqlDataAdapter adap = new SqlDataAdapter("SELECT * FROM NotATable", conn); 
                    /* Exception thrown next */
                    adap.Fill(new DataSet("test"));
                }
                catch (Exception) { }

                using (SqlCommand cmd = new SqlCommand("SELECT TOP 1 Id FROM ARealTable", conn))
                {
                    string result = Convert.ToString(cmd.ExecuteScalar());
                    Console.WriteLine(result);
                }
                Console.ReadKey();

編集:

事前に接続を開いた場合(IDbConnectionオブジェクトでOpenを呼び出す)、IDataAdapterは接続を閉じません。ただし、IDataAdapterに接続の完全な管理を許可すると、接続は閉じられます。

于 2010-03-18T19:54:22.293 に答える