2

EntepriseLibraryを使用してデータベースにクエリを実行しています。クエリを実行するときは、ストアドプロシージャに依存しています。現在、次のようなコードを使用しています。

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ステートメントを入れ子にしてください。

あまり目立たないものの1つは次のとおりです。

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

これはC#IDEで非常にうまくサポートされており、インデントを適切に実行します。または、それについて明確に言うと、誰にでも明らかなコードを書くプログラマーの特徴です。「うわー、男はツールなしで自分のものを知っている」。それは良い。

于 2011-04-28T00:01:30.483 に答える
0

IDataReaderブロック内で使用しているusingため、スコープ外になったときに破棄される(したがって閉じられる)ことが保証されます。DbCommand別のポスターが述べたように、それが適切に処分されるように、あなたも使用ブロックに入れることを忘れないでください。

于 2011-04-27T23:53:07.827 に答える
0

はい、usingブロックはリーダーが廃棄されることを保証します。

ただし、コマンドオブジェクトと接続オブジェクトも破棄する必要があります。そうしないと、ガベージコレクターがそれらを削除するまで閉じられないため、データベース接続は開いたままになります。多くの接続を開いたままにすると、データベースは最終的に新しい接続を拒否します。

于 2011-04-27T23:57:25.817 に答える