ここではレガシーコードを使用していますが、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ステートメントは、オブジェクトの正しい廃棄とリソースの解放を保証します。
忘れた場合は、ガベージコレクターに掃除を任せることになります。これには時間がかかる場合があります。
SqlCommand.ExecuteReader()を使用してインスタンス化されたSqlDataReaderを破棄すると、基礎となる接続がnotクローズ/破棄されることに注意してください。
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を使用して開かれることが重要です。そのため、リーダーを閉じたり破棄したりすると、基になる接続が閉じられます。パターンは次のようになります。
public SqlDataReader ExecuteReader(string commandText)
{
SqlConnection connection = new SqlConnection(...);
try
{
connection.Open();
using(SqlCommand command = new SqlCommand(commandText, connection))
{
return command.ExecuteReader(CommandBehavior.CloseConnection);
}
}
catch
{
// Close connection before rethrowing
connection.Close();
throw;
}
}
そして、呼び出しコードは単にリーダーを破棄する必要があります:
using(SqlDataReader reader = ExecuteReader(...))
{
... do your stuff ...
} // reader and connection are closed here.
安全のため、すべてのSqlDataReaderオブジェクトを sing statement でラップします。
SQLDataReaderを「using」ステートメントでラップするだけです。それはあなたの問題のほとんどの世話をする必要があります。