我们需要使用SqlCommand吗,还是仅仅使用SqlConnection和SqlDataReader就足够了?

6
我从msdn中获取了这段代码。
string connString = "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;";

    using (SqlConnection conn = new SqlConnection(connString))
    {
      SqlCommand cmd = conn.CreateCommand();
      cmd.CommandText = "SELECT CustomerId, CompanyName FROM Customers";

      conn.Open();

      using (SqlDataReader dr = cmd.ExecuteReader())
      {
        while (dr.Read())
          Console.WriteLine("{0}\t{1}", dr.GetString(0), dr.GetString(1));
      }
    }

正如您所看到的,这里没有使用SqlCommand,那么它是否需要呢?


我认为既然连接用于创建命令,那么当您处理它时,命令也将被处理。 - Omu
2个回答

10

对于每个实现了 IDisposable 接口的对象,都需要使用 using 语句。这包括 SqlCommandSqlConnection


这个规则有很少的例外。主要的例外是 WCF 客户端代理。由于设计缺陷,它们的 Dispose 方法有时会抛出异常。如果你在 using 语句中使用了该代理,第二个异常将导致你丢失原始异常。


1
+1,但是为了更清楚地解决WCF问题:这并不意味着您应该忽略客户端是可处理的事实。相反,它意味着您应该将调用包装在try/finally块中,并将Close/Dispose操作包装在finally块中的try/catch块中。非常丑陋... - Mark Seemann
@MarkSeemann 我发现使用重载方法可以帮助清理这样的try...finally混乱。当然,这只是个人意见。 - Pijusn
我不赞同“need”和“rule”这两个词毫无条件地使用。当我们遵循最佳实践“策略”时,这就是一种“规则”。然而,这个问题引发了一个关于SqlCommand(DbCommand)的问题,它是由SqlConnection(DbConnection)构建/初始化的。在调用DbCommand.Dispose()时,DbConnection是否被处理? - Brett Caswell
@brett:一般来说,不合格的语句更好。也许有20%的.NET开发人员应该考虑违反这个规则。我指的是最有经验的20%。对于其他人,应该是“必要”和“规则”。 - John Saunders
1
@brett,关于DbConnection,请看一下代码。但依赖未经记录的功能是不明智的。 - John Saunders

4

IDisposable 不是关于内存使用的,而是关于资源使用的。 - John Saunders
我认为由于连接用于创建命令,因此当您处理它时,该命令也会被处理。 - Omu
但是SqlCommand可能没有保持任何资源打开,因为创建SqlCommand的Connection已经关闭了... - rohancragg
@Omu:不,没有这样的记录,所以假设它不是真的。 - John Saunders
@rohancragg:对于这样的事情,我不会轻易做出假设。即使在当前版本中是真实的,也可能在某个未来的版本中不再适用。 - John Saunders
公平的,我无论如何都同意,我个人会尽可能地在使用中加入。 - rohancragg

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