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 窗体应用程序的这段代码证明了这一点。第一个消息框将显示“打开”,第二个消息框将显示“关闭”。

              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 回答