SqlDataAdapter在Fill()函数后会关闭SqlConnection吗?

11

SqlDataAdapterFill() 函数执行后,是否会自动关闭 SqlConnection 连接,还是需要手动关闭?

string cnStr = @"Data Source=TEST;Initial Catalog=Suite;Persist Security Info=True;User ID=app;Password=Immmmmm";
cn = new SqlConnection(cnStr);
SqlCommand cmd = new SqlCommand("SELECT TOP 10 * FROM Date", cn);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);

DataSet ds = new DataSet();
adapter.Fill(ds);

cn.Close() // ????????

Console.WriteLine(ds.Tables[0].Rows.Count);
Console.WriteLine(cn.State);
2个回答

16

在你当前的使用方式下,它将会为你关闭:

如果在调用Fill之前IDbConnection已经关闭,则会重新打开以检索数据,然后关闭。如果在调用Fill之前连接已经打开,则连接保持打开状态。

http://msdn.microsoft.com/en-us/library/zxkb3c3d.aspx

我认为最好总是用using语句显式处理它:

using (SqlConnection conn = new SqlConnection(""))
{
    conn.Open();

    // Do Stuff.

} // Closes here on dispose.

这种方法通常更易读,并且不需要人们理解SqlDataAdapter.Fill的内部工作原理,只要理解using语句和连接即可。

但是,如果您知道适配器使用它之前连接已关闭(例如,刚刚创建了该连接),并且它未用于其他任何事情,则您的代码是完全安全和有效的。

个人而言,我会写出类似以下的代码:

    string cnStr = "Data Source=TEST;Initial Catalog=Suite;Persist Security Info=True;User ID=app;Password=Immmmmm";
    DataSet ds = new DataSet();

    using (SqlConnection cn = new SqlConnection(cnStr))
    using (SqlCommand cmd = new SqlCommand("SELECT TOP 10 * FROM Date", cn))
    using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
    { 
        conn.Open();
        adapter.Fill(ds);       
    }

如果我在不使用构造函数cn的情况下编写此代码,则无论何时在功能退出之前都会处于关闭状态。 - Wachburn
1
@Wachburn 确实如此,查阅 MSDN 可以证实这一点。抱歉,我第一次没有注意到这个问题。 - Adam Houldsworth
是的,基本上是这样。我相信它可以双向工作,个人偏好而已。 - Adam Houldsworth
1
@ConcreteGannet 刚刚尝试了一下,以防C# 7有所改变,但不幸的是,只有在类型共享时才为真,例如 using (IDisposable conn = new SqlConnection(), comm = new SqlCommand()),你不能这样做 using (SqlConnection conn = new SqlConnection(), SqlCommand comm = new SqlCommand()),因此在这种情况下需要三个 using 语句。 - Adam Houldsworth
谢谢@AdamHouldsworth,我没有意识到这一点。using并不像我想象的那么酷。我同意三个using是最好的答案。您可以将它们全部声明为IDisposable,然后在块内进行向下转换,但这非常丑陋。您可以在using之前声明它们,但这很危险,因为变量在被处理后仍然处于范围内。请随意对我上面的评论进行投票否决,SO不会让我 :-) - Concrete Gannet
显示剩余6条评论

5
据我所知,您需要自己关闭连接。最好的方法是:
using(SqlConnection con = new SqlConnection())
{
   // you code 
}

这将自动关闭您的连接

在处理可释放对象时,C# 中的 using 块非常方便。可释放对象是指当调用 dispose 时可以显式释放其使用的资源的对象。由于 .Net 垃圾回收是非确定性的,因此无法预测对象何时被垃圾回收。

阅读此文章以了解更多详细信息:理解 C# 中的 'using' 块


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