私は通常次のようなコードを使用します:
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
{
var command = connection.CreateCommand();
command.CommandText = "...";
connection.Open();
command.ExecuteNonQuery();
}
command
は自動的に破棄されますか?またはそうではなく、それをusing
ブロックにラップする必要がありますか? SqlCommand
を破棄する必要がありますか?
これを行うだけです:
using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
using(var command = connection.CreateCommand())
{
command.CommandText = "...";
connection.Open();
command.ExecuteNonQuery();
}
コマンドでdisposeを呼び出さなくても、それほど悪いことはありません。ただし、Disposeを呼び出すと ファイナライザーへの呼び出しが抑制されます 、disposeを呼び出すとパフォーマンスが向上します。
最も安全なポリシーは、オブジェクトがIDisposable
を実装している場合、明示的にまたはusingブロックを介して、オブジェクトに対して常にDispose()
を呼び出すことです。必須ではない場合もありますが、とにかく呼び出しても問題は発生しません(クラスが正しく記述されている場合)。また、実装がいつ変更されるかはわかりません。つまり、以前は呼び出しが必要でなかった場所で、今では確実に必要になります。
与えた例では、コマンド用に内側のusingブロックを追加したり、接続用の外側のusingブロックを維持したりできます。
はい、実装が現在あまり機能していない場合でも、将来どのように変更されるかはわかりません(たとえば、新しいフレームワークバージョン)。一般に、IDisposable
を実装するすべてのオブジェクトを安全側に配置する必要があります。
ただし、操作が延期され、スコープ全体を制御できない場合(たとえば、非同期で作業する場合、またはSqlDataReader
などを返す場合)、CommandBehavior
をCloseConnection
に設定して、リーダーが完了するとすぐに接続は適切に閉じられます/破棄されます。
実際には、Dispose
をスキップできます。リソースを解放することはありません。 SQLCommandコンストラクターがそれを行う なので、ファイナライズも抑制しません。
理論的には、Microsoftはアンマネージリソースを保持するように実装を変更できますが、それを行うずっと前にComponent
基本クラスを削除するAPIが提供されることを願っています。
この種のものは、 Reflector またはdotPeekまたは https://referencesource.Microsoft.com/ を使用して見つけることができます。
私は小さな掘り出し物を持っていました(私はそれを一生懸命試みなかったので、これの残りを完全に確信するためにあなた自身を掘ることをお勧めします)そしてあなたが接続を殺すとき関連する子供たちの処分がないように見えますその接続で。さらに、コマンドの破棄が実際にそれほど多くのことを行うようには見えません。フィールドをnullに設定し、コンテナーから切り離して(これにより、マネージメモリリークを防ぐことができます)、イベントを発生させます(これは重要かもしれませんが、誰がこのイベントをリッスンしているかわかりません)。
いずれにせよ、usingブロックでこのようなものを使用するか、接続を保持するオブジェクトのdisposeパターンを使用して確実に破棄することをお勧めします(コマンドをしばらく保持する場合)。
私の意見では、Dispose
とSqlConnection
の両方に対してSqlCommand
を呼び出すことは良い習慣です、以下のコードを使用してください
using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
try{
using(var command = connection.CreateCommand())
{
command.CommandText = "...";
connection.Open();
command.ExecuteNonQuery();
}
}
catch(Exception ex){ //Log exception according to your own way
throw;
}
finally{
command.Dispose();
connection.Close();
connection.Dispose();
}