DataAdapter.Fill () закрывает свое соединение при возникновении исключения? - PullRequest
17 голосов
/ 18 марта 2010

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

Мой вопрос: Закрывает ли оно также соединение, если .Fill () вызывает исключение? (из-за невозможности доступа к SQL Server или как-то еще). Происходит ли утечка соединения или имеется встроенное предложение Окончание, чтобы удостовериться, что соединение закрыто.

Пример кода:

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)

Ответы [ 2 ]

21 голосов
/ 18 марта 2010

Если соединение открыто до вызова метода 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());
        }
1 голос
/ 18 марта 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();

Edit:

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

...