2016-04-02 18 views
3

私はこれについて少し理解する必要があります。データベースへの接続を開くと、開いたままにすることはできますか?C#データベース接続を閉じる

この接続はどのように閉じますか?

良い練習ですか、悪い練習ですか?

は現在、私はしかし、私が見てきた例のいくつかは、無データベース近いとこのようなことは問題

oCON.Open(); 
oCMD.ExecuteNonQuery(); 
oCON.Close(); 

に動作しないデータベースに要求をしているしています。

oCON.Open(); 
oCMD.ExecuteNonQuery(); 

この接続はどのように閉じられますか?

この悪い習慣ですか?

答えて

4

これはよくある質問のように重複を探していました。私が見つけた一番上の答えはthis oneですが、私は与えられた答えが嫌いです。

いつもあなたが完了したらすぐに接続を終了してください。データベースには有限の数の接続があり、多くのリソースが必要です。

近いが発生したことを確認するには、「古い学校」の方法は、try/catch/finallyブロックしていました:

SqlConnection connection; 
SqlCommand command; 

try 
{ 
    // Properly fill in all constructor variables. 
    connection = new SqlConnection(); 
    command = new SqlCommand(); 

    connection.Open(); 
    command.ExecuteNonQuery(); 

    // Parse the results 
} 
catch (Exception ex) 
{ 
    // Do whatever you need with exception 
} 
finally 
{ 
    if (connection != null) 
    { 
     connection.Dispose(); 
    } 
    if (command != null) 
    { 
     command.Dispose(); 
    } 
} 

しかし、using文は、それが自動的にオブジェクトを廃棄しますとして好ましい方法です。例外がスローされます場合でも

try 
{ 
    using (var connection = new SqlConnection()) 
    using (var command = new SqlCommand()) 
    { 
     connection.Open(); 
     command.ExecuteNonQuery(); 

     // Do whatever else you need to. 
    } 
} 
catch (Exception ex) 
{ 
    // Handle any exception. 
} 

using文は、それはまだ、コードの実行が停止する前に作成されますオブジェクトを破棄し、その中に特別です。コードを簡潔かつ読みやすくします。

コメントでchristophanoで述べたように、あなたのコードはILまでコンパイルされるとき、それは実際に上記の例で行われているものを複製、try/finallyブロックとして書き込まれます。

+1

実際には、「使用しています」というのは非常に最初からあり、2001年のC#1にはすでに存在していました。 –

+0

うわー、それを見てください。私はそれから私の答えを編集します。 – krillgar

+0

良い答え。 usingステートメントは実際にコンパイラによってtry/finallyブロックとして記述されることに言及する価値があります。 – christophano

1

あなたのSqlConnectionusingブロックになりたい:

using(var connection = new SqlConnection(connectionString)) 
{ 
... 
} 

SqlConnectionもそれを閉じる、配置されるようになります。

あなたの視点から、接続は閉じられています。実際には、接続は実際には閉じられていない場合もあります。 SQL接続を確立するには時間とリソースが必要です。そのため、その接続は即座に終了しません。彼らは開いたままにして、しばらくの間アイドル状態にして、再利用できるようにします。これは接続プールと呼ばれています。したがって、接続を開くと、実際に新しい接続を開いていない可能性があります。接続プールから1つを取得している可能性があります。そしてあなたがそれを閉じるとすぐに閉じることはなく、プールに戻ります。

これはすべてバックグラウンドで処理されており、私たちの接続で明示的に行うことは変わりません。私たちは常にそれらをできるだけ早く閉じます。その後、.NET Frameworkによって実際に閉じられる時期が決まります。 (その動作を何らかの形で制御することは可能ですが、ほとんど必要ありません)

0

作業単位のリポジトリパターンを見てみましょう。 データベースへのコマンドを操作するクラスに接続コンテキストを挿入する必要があります。

SQL実行クラス - リポジトリクラスのように、接続を作成しないでください。それはテスト可能ではなく、SRPのパラダイムを傷つけます。 コンストラクタのようにIDbConnectionオブジェクトを受け入れる必要があります。 IDbConnectionの背後にSqlConnection,MysqlConnectionまたはOracleConnectionのインスタンスがある場合、リポジトリは注意しないでください。

すべてのADO.NET接続オブジェクトはIDbConnectionと互換性があります。