Подтвердить что ты не робот

Завершает ли DataAdapter.Fill() его соединение при вызове Exception?

Я использую ADO.NET(.NET 1.1) в устаревшем приложении. Я знаю, что DataAdapter.Fill() открывает и закрывает соединения, если соединение не было открыто вручную, прежде чем оно будет передано в DataAdapter.

Мой вопрос: Закрывает ли он соединение, если .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)
4b9b3361

Ответ 1

Если соединение открыто до вызова метода Fill(), то нет, соединение не будет закрыто DataAdapter.

Однако, если вы явно не открываете соединение, и вместо этого DataAdapter откроет и закроет соединение в команде Fill(), тогда соединение будет закрыто при ошибке.

Это может быть подразумевается из нескольких источников документации, включая этот: Стратегии доступа к данным с использованием ADO.NET и SQL

Кроме того, это можно продемонстрировать в коде, написав процедуру, которая будет выходить из строя, а затем проверять состояние соединения.

Этот код из приложения Windows Forms подтверждает это. В первом окне сообщения будет указано "Открыть" и второе "Закрыто".

              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());
        }

Ответ 2

Он не закрывает соединение. Этот пример работает и выводит идентификатор "ARealTable"

            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();

Edit:

Если вы открываете соединение перед рукой (вызов Open на объекте IDbConnection), IDataAdapter не будет закрывать его. Однако, если вы разрешите IDataAdapter полностью управлять соединением, он будет закрыт.