【问题标题】:Does SqlDataAdapter close the SqlConnection after Fill() function?SqlDataAdapter 是否在 Fill() 函数后关闭 SqlConnection?
【发布时间】:2011-09-12 13:33:51
【问题描述】:

SqlDataAdapter 是在 Fill() 函数之后关闭 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);

【问题讨论】:

    标签: c# .net sql-server sqlconnection sqlconnection.close


    【解决方案1】:

    在您当前的使用情况下,它将为您关闭:

    如果 IDbConnection 在调用 Fill 之前关闭,打开它以检索数据和 然后关闭。如果在调用 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 的情况下编写此代码,则在函数退出之前具有 Closed 状态
    • @Wachburn 确实如此,咨询 MSDN 证实了这一点。抱歉,我第一次没听懂。
    • 如果命令执行成功,它会为你处理关闭它,但是在异常情况下呢? (死锁、超时等)
    • @JoelC using 语句也会在异常时调用 dispose,它只是在底层编译为 try-finally 块。
    • @ConcreteGannet 刚刚尝试过,以防 C# 7 发生了一些变化,但不幸的是,这仍然只有在共享类型时才适用,例如 using (IDisposable conn = new SqlConnection(), comm = new SqlCommand()) 你不能这样做 using (SqlConnection conn = new SqlConnection(), SqlCommand comm = new SqlCommand()) 所以三个 @987654330在这种情况下需要 @ 语句。
    【解决方案2】:

    据我所知,您需要自己关闭连接

    最好的办法是

    using(SqlConnection con = new SqlConnection())
    {
       // you code 
    }
    

    这会自动关闭你的连接

    在处理一次性对象时,在 C# 中使用块非常方便。 Disposable 对象是那些在调用 dispose 时可以显式释放它们使用的资源的对象。正如我们所知,.Net 垃圾收集是不确定的,因此您无法准确预测对象何时会被垃圾收集。

    阅读这篇文章了解更多详情:understanding ‘using’ block in C#

    【讨论】:

      猜你喜欢
      • 2012-06-29
      • 2011-05-22
      • 2013-04-24
      • 1970-01-01
      • 1970-01-01
      • 2011-09-01
      • 1970-01-01
      • 2010-11-14
      • 1970-01-01
      相关资源
      最近更新 更多