web-dev-qa-db-ja.com

usingステートメント内のSqlConnection.Close()

私はこのコードを使用しています:

_    public void InsertMember(Member member)
    {
        string INSERT = "INSERT INTO Members (Name, Surname, EntryDate) VALUES (@Name, @Surname, @EntryDate)";

        using (sqlConnection = new SqlConnection(sqlConnectionString_WORK))
        {
            sqlConnection.Open();

            using (SqlCommand sqlCommand = new SqlCommand(INSERT, sqlConnection))
            {
                sqlCommand.Parameters.Add("@Name", SqlDbType.VarChar).Value = member.Name;
                sqlCommand.Parameters.Add("@Surname", SqlDbType.VarChar).Value = member.Surname;
                sqlCommand.Parameters.Add("@EntryDate", SqlDbType.Date).Value = member.EntryDate;

                sqlCommand.ExecuteNonQuery();
            }
        }
    }
_

sqlConnection.Close();を廃棄する前に追加しないと間違っていますか?というのは。エラーは表示されず、まったく問題はありません。最初に閉じたほうがいいですか?はいの場合、なぜですか?

28
Etrit

する必要がない Close or Disposeusingブロックが自動的に処理します。

[〜#〜] msdn [〜#〜] から述べたとおり:

次の例では、SqlConnectionを作成して開き、そのプロパティの一部を表示します。接続は、usingブロックの最後で自動的に閉じられます。

private static void OpenSqlConnection(string connectionString) 
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
        Console.WriteLine("ServerVersion: {0}", connection.ServerVersion);
        Console.WriteLine("State: {0}", connection.State);
    } 
}
36
Darren

オブジェクトのメソッドを呼び出している間に例外が発生した場合でも、using statement ensures that Dispose is calledYou can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block;実際、これはusingステートメントがコンパイラーによって変換される方法です[〜#〜] msdn [〜#〜]

最終的にあなたのコード行

  using (sqlConnection = new SqlConnection(sqlConnectionString_WORK))

コンパイラがtry finally blockを呼び出すことにより、通常のIDisposable object in the finallyに変換されます

8
Suraj Singh

Usingステートメントはtry finallyブロックであり、最終的なブロックにはconnection.Dispose()呼び出しが含まれます。したがって、独立したconnection.Close()ステートメントは実際には必要ありません。

利点は、finallyブロックが常に実行されるため、例外が発生した場合でも確実に処理できることです。

try
{
sqlConnection.Open();
// ....
}
finally
{
if(sqlConnection != null)
      sqlConnection.Dispose();
}
4
V4Vendetta

CloseメソッドのMSDNドキュメント によると:

CloseまたはDisposeを呼び出して、接続を明示的に閉じる必要があります。 CloseDisposeは機能的に同等です。

したがって、Disposeを呼び出すと(暗黙のうちにusingを使用しても)、ベースがカバーされます。

あなたの場合に固有ではありませんが、Closeusingステートメントでラップされたときに常に効果的に呼び出されることに注意してください-not省略すると、適切なtry/catch/finally処理なしで例外が発生します。

4
Grant Thomas

SqlConnection.Close()を追加しないと間違っていますか?処分する前に

いいえ、Using内で接続を使用している限り長くはありません。 usingスコープを離れると、SQL接続のためにDisposeが呼び出されます。 既存の接続を閉じるになり、すべてのリソースも解放されます。

4
Ehsan

いいえ、間違っていません。 sqlConnectionは、singブロックを渡してDisposeメソッドを呼び出した後、接続を閉じます。 SqlConnection.Close()メソッドと等しいSqlConnection.Dispose()。

MSDNから:SqlConnectionが範囲外になった場合、閉じられません。したがって、CloseまたはDisposeを呼び出して接続を明示的に閉じる必要があります。 CloseとDisposeは機能的に同等です。

3
Alex

Usingを使用しています。これは、オブジェクトをDispose()します。

Usingステートメントの外部の接続を使用する場合、はい-終了したら接続を閉じる必要があります。

3
Hexie

これは非常に興味深い質問であり、多くの人が考えるほど明白ではありません。 usingステートメントは、接続を使用するすべてのオブジェクトが破棄される場合にのみ、接続に対して正しく機能します。しばらく前に、SQLサーバーで開かれた接続に問題がありました。接続はステートメントを使用して内部にあるため、すべてが正常に見えましたが、開発者の1人がSqlDataReaderでいくつかのメソッドを作成し、それを正しく閉じませんでした。そのため、接続は解放されませんでした。

この理由は、ガベージコレクションの動作方法です。簡単に言えば、オブジェクトへのアクティブな参照がない場合、オブジェクトのマップを作成して、実際にオブジェクトを破棄します。

0
Chris W.