【问题标题】:SqlCommand with using statement带有 using 语句的 SqlCommand
【发布时间】:2014-06-04 20:15:57
【问题描述】:

我看到在大多数示例中SqlCommand 是这样使用的

using (SqlConnection con = new SqlConnection(CNN_STRING))
{
    using (SqlCommand cmd = new SqlCommand("Select ID,Name From Person", con))
    {
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        DataSet ds = new DataSet();
        da.Fill(ds);           
        return ds;
    }
}

我知道我们为什么使用using 语句。但是SqlCommand 不包含Close() 方法,那么我们真的应该在using 语句中使用它吗?

【问题讨论】:

  • 在这个例子中,你不应该真正关心关闭连接,因为Fill() 管理连接本身,即使你没有使用using 语句。
  • 是的,你是对的。来自MSDN:“与SELECT语句关联的连接对象必须有效,但不需要打开。如果在调用Fill之前关闭连接,则打开它以检索数据,然后关闭。如果连接是在调用 Fill 之前打开,它保持打开状态。” - msdn.microsoft.com/en-us/library/377a8x4t.aspx

标签: c# sqlconnection sqlcommand using-statement


【解决方案1】:

因为它也实现了IDisposable

Using 语句的目的是当控制到达使用结束时,它会释放该对象的 using 块并释放内存。它的目的不仅仅是为了自动关闭连接,基本上它会处理连接对象,显然连接也因此而关闭。

它的目的是释放我们在 Using 语句中使用的资源。

根据MSDN:

通常,当您使用IDisposable 对象时,您应该在 using 语句中声明和实例化它。 using 语句以正确的方式调用对象上的Dispose 方法,并且(当您如前所示使用它时)它还会导致对象本身在调用Dispose 时立即超出范围。在 using 块中,对象是只读的,不能修改或重新分配。

using 语句可确保调用 Dispose,即使在您调用对象上的方法时发生异常也是如此。您可以通过将对象放在 try 块中然后在 finally 块中调用 Dispose 来获得相同的结果;事实上,这就是编译器翻译 using 语句的方式。前面的代码示例在编译时扩展为以下代码(注意额外的花括号以创建对象的有限范围):

注意:

您可以实例化资源对象,然后将变量传递给 using 语句,但这不是最佳实践。在这种情况下,对象在控制离开 using 块后仍保留在范围内,即使它可能不再有权访问其非托管资源。换句话说,它将不再被完全初始化。如果您尝试在 using 块之外使用该对象,则可能会引发异常。因此,通常最好在 using 语句中实例化对象并将其范围限制在 using 块中。

【讨论】:

  • 如何理解一个类是否实现了 IDisposable?
  • 一个没有实现IDisposable的类不能和using一起使用,它必须实现IDisposable
  • 我的问题是我们怎么知道 SqlCommand 实现了 Idisposible?我是新手,所以我想学习
  • 你可以检查一个 Dispose() 方法是否可以与它实现 IDisposable 的对象一起使用,否则它不会实现
  • 意味着如果你看到一个方法 Dispose 可以通过类对象访问它的实现 IDisposable
【解决方案2】:

SqlCommand 确实实现了IDisposableusing 语句将在 using 块完成之前调用 .Dispose()。我不确定SqlCommand.Dispose() 做了什么,但最好在您完成的实例上调用.Dispose(),即它可能会清除数据库连接。

【讨论】:

  • SqlCommand.Dispose()的目的是释放SqlCommand使用的所有资源。在他的例子中,对象是 cmd。
  • 如何理解一个类是否实现了 IDisposable?
  • 多种方式 - 在 Visual Studio 中,转到实例的类型并右键单击它,选择“转到定义”。该窗口将告诉您该类型是否实现了IDisposable
  • 现在源代码可用,您可以看到它的作用。不多,但确实有作用:referencesource.microsoft.com/#System.Data/System/Data/…
  • 如果使用 Jason 的技巧,右键单击 SqlCommand,转到定义,然后查看public sealed class SQLiteCommand : DbCommand, ICloneable,因此它继承自 DbCommand。右键单击 DbCommand,转到定义,然后查看它继承自 IDisposable。
猜你喜欢
  • 1970-01-01
  • 2019-12-23
  • 2011-09-03
  • 2022-01-13
  • 2011-02-25
  • 2019-02-05
  • 2010-11-10
  • 1970-01-01
相关资源
最近更新 更多