私はここでレガシーコードを扱っています。SqlDataReader
の多くのインスタンスが閉じられたり廃棄されたりすることはありません。接続は閉じていますが、読者を手動で管理する必要があるかどうかはわかりません。SqlDataReaderを手動で閉じて処分する必要がありますか?
パフォーマンスが低下する可能性がありますか?
私はここでレガシーコードを扱っています。SqlDataReader
の多くのインスタンスが閉じられたり廃棄されたりすることはありません。接続は閉じていますが、読者を手動で管理する必要があるかどうかはわかりません。SqlDataReaderを手動で閉じて処分する必要がありますか?
パフォーマンスが低下する可能性がありますか?
は次のように読者を使用しないようにしてください:
代わりSqlConnection connection = new SqlConnection("connection string");
SqlCommand cmd = new SqlCommand("SELECT * FROM SomeTable", connection);
SqlDataReader reader = cmd.ExecuteReader();
connection.Open();
if (reader != null)
{
while (reader.Read())
{
//do something
}
}
reader.Close(); // <- too easy to forget
reader.Dispose(); // <- too easy to forget
connection.Close(); // <- too easy to forget
、それらは、usingステートメントでラップ:
using(SqlConnection connection = new SqlConnection("connection string"))
{
connection.Open();
using(SqlCommand cmd = new SqlCommand("SELECT * FROM SomeTable", connection))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader != null)
{
while (reader.Read())
{
//do something
}
}
} // reader closed and disposed up here
} // command disposed here
} //connection closed and disposed here
usingステートメントは、オブジェクトおよびリソースの解放の正しい処分を保証します。
忘れてしまった場合は、ガベージコレクタにクリーニングを残していますが、これには時間がかかることがあります。
安全のためには、すべてのSqlDataReaderオブジェクトをusing statementにラップしてください。
"using"ステートメントでSQLDataReaderをラップするだけです。それはあなたの問題の大部分を処理する必要があります。
SqlCommand.ExecuteReader()を使用してインスタンス化されたSqlDataReaderを廃棄すると、ではなく、が基になる接続を閉じる/破棄することに注意してください。
一般的なパターンは2つあります。最初に、読者は、接続の範囲内で開閉される:
using(SqlConnection connection = ...)
{
connection.Open();
...
using(SqlCommand command = ...)
{
using(SqlDataReader reader = command.ExecuteReader())
{
... do your stuff ...
} // reader is closed/disposed here
} // command is closed/disposed here
} // connection is closed/disposed here
場合によっては、データのアクセス方法は、接続を開き、リーダーを返しておくと便利です。この場合、返されたリーダーがCommandBehavior.CloseConnectionを使用して開かれていることが重要です。これにより、リーダーのクローズ/ディスポジションによって基底の接続が閉じられます。パターンは、このようなものになります。
と、呼び出し元のコードをちょうどので、読者を配置する必要があります。十分な
using(SqlDataReader reader = ExecuteReader(...))
{
... do your stuff ...
} // reader and connection are closed here.
SqlCommandオブジェクトにClose()メソッドはありません。 – Dave
メソッドがSqlDataReaderを返す2番目のコードスニペットでは、コマンドは破棄されません。それは大丈夫ですか?コマンドを破棄(使用ブロックで囲んでください)してからリーダーを返すのは大丈夫ですか? – alwayslearning
@alwayslearningこれはまさに私が持っているシナリオです...... SqlDataReaderを呼び出し元に返すときにSqlCommandを閉じたり破棄したりできますか? – ganders
いずれのサンプルでも.Close()ステートメントは必要ありません。これは.Dispose()呼び出しによって処理されます。 –
いいえ、コードに – Codebrain
のオプションとして閉じるとマークしました。このサンプルは、閉鎖/廃棄される基底の接続を表示していません。これが最も重要なことです。 – Joe