Закрывает ли DataAdapter.Fill () свое соединение при возникновении исключения?

Я использую 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)

person motto    schedule 18.03.2010    source источник
comment
Не зная этого точно, я бы предположил, что это так. Однако вы можете использовать Reflector (red-gate.com/products/reflector) для изучите реализацию и посмотрите, реализуется ли она наконец.   -  person AxelEckenberger    schedule 18.03.2010


Ответы (2)


Если соединение открыто до вызова метода 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());
        }
person David    schedule 18.03.2010

Он не закрывает соединение. Этот пример работает и выводит идентификатор «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();

Изменить:

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

person scottm    schedule 18.03.2010
comment
Да, если вы открываете его, вы несете ответственность за его закрытие. Однако я смотрю на ситуацию, когда DataAdapter открывает для меня соединение. - person motto; 18.03.2010
comment
В этом случае он будет закрыт DataAdapter. - person scottm; 18.03.2010
comment
но тогда, если вы позволите адаптеру данных обрабатывать закрытие, будет ли работать команда вставки? Я согласен, что выбор и заполнение будут работать. - person variable; 18.08.2014