2

我正在使用企业库来查询我的数据库。当我运行查询时,我依赖于存储过程。目前,我正在使用如下代码:

Database database = DatabaseFactory.CreateDatabase();
DbCommand command = database.GetStoredProcCommand("MyStoredProcedureName");

database.AddInParameter(command, "filter", DbType.String, filter);

Result result = null;
using (IDataReader reader = database.ExecuteReader(command))
{
  if (reader.Read())
    result = new Result(reader);
}
return result;

我如何确定我的阅读器已关闭?我注意到我的应用程序有时无法在后续加载时加​​载。我怀疑有些东西没有打开。但我不知道如何追踪它。

根据上面显示的代码,阅读器不应该因为“使用”而被关闭和处置吗?

谢谢!

4

5 回答 5

2

阅读器正在被处理和关闭,但 DbCommand 不是。你也应该把它放在 using 语句中。

于 2011-04-27T23:52:36.503 回答
2

阅读器保证是关闭的,因为它被包裹在using. 但是,DbCommand也实现了IDisposable,并且没有使用/处置它的调用。

Database database = DatabaseFactory.CreateDatabase();
using(DbCommand command = database.GetStoredProcCommand("MyStoredProcedureName"))
{
    //snip (no change)
}
return result;

阅读器不代表底层连接,只是用于读取响应的缓冲区。

于 2011-04-27T23:53:23.590 回答
1

你负责处理读者。您没有处理 DbCommand 和 Database 对象的处理。不确定它们是什么,但很确定它们也实现了 IDisposable 。他们总是这样做。以您知道的最漂亮的方式嵌套您的using语句。

不太明显的一个是:

using (var obj = new Foo())
using (var obj2 = new Bar()) {
    // etc..
}

C# IDE 很好地支持它,它的缩进恰到好处。或者说清楚一点,一个程序员的标志是写代码让任何人都明白:“哇,伙计不用工具就知道他的东西”。那挺好的。

于 2011-04-28T00:01:30.483 回答
0

由于您IDataReaderusing块中使用,因此当它超出范围时,保证会被处置(并因此关闭)。正如另一张海报所提到的,不要忘记将你DbCommand的也放入 using 块中,以便妥善处理。

于 2011-04-27T23:53:07.827 回答
0

是的,该using块确保阅读器将被处置。

但是,您也应该处置您的命令和连接对象。如果你不这样做,它们将不会被关闭,直到垃圾收集器来移除它们,所以数据库连接将保持打开状态。如果您打开大量连接,数据库最终将拒绝新连接。

于 2011-04-27T23:57:25.817 回答