DataAdapter.Fill()在抛出异常时是否会关闭连接?

21

我正在使用ADO.NET (.NET 1.1)在一个旧应用程序中。我知道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)

1
虽然我不确定它是否有,但我认为它应该有。但是,您可以使用Reflector(http://www.red-gate.com/products/reflector/)来查看实现并查看它是否实现了finally。 - AxelEckenberger
2个回答

24

如果在调用 Fill() 方法之前连接已经打开,那么不,DataAdapter 不会关闭连接。

然而,如果您没有显式打开连接,而是让 DataAdapter 在 Fill() 命令中打开和关闭连接,那么连接将在出现错误时关闭。

这可以从多个文档来源推断出来,包括这个:Data Access Strategies Using ADO.NET and SQL

此外,可以通过编写一个会出错的例程并检查连接状态来证明这一点。

这个 Windows Forms 应用程序中的代码证明了它。第一个消息框将显示 "Open",第二个消息框将显示 "Closed"。

              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

不会关闭连接。这个例子可以正常工作,并输出"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完全管理连接,则会关闭连接。


是的,如果你打开了它,你就要自己负责关闭它。但是我正在看一个情况,其中DataAdapter为我打开连接。 - motto
在这种情况下,它将由DataAdapter关闭。 - scottm
但是如果您允许DataAdapter处理关闭,那么InsertCommand会起作用吗?我同意Select和Fill会起作用。 - variable

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接