SqlConnection SqlCommand SqlDataReader IDisposable

Den*_*nis 18 .net c# sql-server ado.net

SqlConnection,SqlCommand并且SqlDataReader都实现了IDisposable界面.我读到了一个总是包装IDisposablesusing块的最佳实践.

因此,我查询数据的常见场景看起来就像这样(在更大的上下文中,像linq2sql这样的映射工具是合适的,但我们假设我们想在这里使用这种方法):

using (SqlConnection cn = new SqlConnection("myConnectionstring"))
{
    using (SqlCommand cm = new SqlCommand("myQuery", cn))
    {
        // maybe add sql parameters
        using (SqlDataReader reader = cm.ExecuteReader())
        {
             // read values from reader object
             return myReadValues;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是正确的方式还是被认为是矫枉过正?我对这种嵌套using块有点不确定,但当然我想以正确的方式做到这一点.谢谢!

Mik*_*oud 15

这是100%正确的方法.如果类利用IDisposable它,则应将其包装在using语句中以确保Dispose()调用该方法.此外,不应轻率地与外部技术进行通信 - 不管那样的SQL Server.该SqlCommand对象的实现IDisposable有很好的理由.下面的代码是对象的Dispose()方法SqlCommand:

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        this._cachedMetaData = null;
    }
    base.Dispose(disposing);
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它正在释放对该_cachedMetaData对象的引用,以便它也可以被清除.


Mat*_*eid 5

您可以使用以下排版方式使代码更靠近左侧:

using (SqlConnection cn = new SqlConnection("myConnectionstring"))
using (SqlCommand cm = new SqlCommand("myQuery", cn))
using (SqlDataReader reader = cm.ExecuteReader())
{
     // read values from reader object
     return myReadValues;
}
Run Code Online (Sandbox Code Playgroud)

正如其他已经指出的那样,使用三个嵌套using块是正确的.

  • 我认为这段代码不起作用,因为连接永远不会打开.堆叠它看起来不错,但它不可行,因为总是需要完成的东西(cn.Open(),cm.Parameters.AddWithValue()等) (3认同)