2012-04-13 39 views
8

異なるテーブルで複数のSELECTクエリを実行する場合、それらのすべてに対して同じSqlDataReaderとSqlConnectionを使用できますか?次のことが賢明だろうか? (私はこれを速く入力したので、try/catchが欠けている):SqlConnectionとSqlDataReaderの再利用

MySqlCommand myCommand = new MySqlCommand("SELECT * FROM table1", myConnection); 

myConnection.Open(); 
SqlDataReader myDataReader = myCommand.ExecuteReader(); 

while(myReader.Read()) 
{ 
    //Perform work. 
} 

myCommand.commandText = "SELECT * FROM table2"; 

myReader = myCommand.ExecuteReader(); 

while(myReader.Read()) 
{ 
    //Perform more work 
} 

myReader.Close(); 
myConnection.Close(); 

ありがとう。

+0

Entity Frameworkを使用する必要があります。 –

+1

おそらく参考になります:http://stackoverflow.com/questions/9705637/executereader-requires-an-open-and-available-connection-the-connections-curren/9707060#9707060 –

+1

上記のコードは間違いを見せていますか?そうでない場合、それは確かに大丈夫です。 – sarwar026

答えて

20

異なるスレッドからの同じ接続で複数のクエリを同時に実行しようとしない限り、それぞれに同じ接続を使用できます。

ExecuteReaderへの各呼び出しは、新しいリーダーの新しいインスタンスを返します。再利用しているのは、そのリーダーへの参照を保持する変数だけです。ここでは問題がありますが、あなたは最後の読者を明示的に閉じて、後で最初のものをGCしておくだけです。

コマンドを再利用することもできますが、パラメータなどを指定する場合は、次のクエリにも適用されない限り、次のクエリでそれらをクリアする必要があります。

try/finallyブロックを使用してリソースをクリーンアップするか、usingステートメントを使用してコードの残りの部分を防止する例外が存在する場合でもリソースをクリーンアップするコードをすばやく変更する必要があります実行から。

using (var myConnection = GetTheConnection()) 
{ 
    myConnection.Open(); 

    var myCommand = new MySqlCommand("SELECT * FROM table1", myConnection)) 
    using (var myDataReader = myCommand.ExecuteReader()) 
    { 
    while(myReader.Read()) 
    { 
     //Perform work. 
    } 
    } // Reader will be Disposed/Closed here 

    myCommand.commandText = "SELECT * FROM table2"; 
    using (var myReader = myCommand.ExecuteReader()) 
    { 
    while(myReader.Read()) 
    { 
     //Perform more work 
    } 
    } // Reader will be Disposed/Closed here 
} // Connection will be Disposed/Closed here 

注:GetTheConnectionはあなたの接続インスタンスを取得するために使用され、これまでどのようなメカニズムのためだけのプレースホルダ機能です。

+0

ありがとうございます。だから、毎回の実行後にリーダーオブジェクトを閉じるだけでいいと思う。 – PaulG

+1

実際には、SqlCommandのパラメータを提供しています。myCommand.Parameters.Clear()を使用する必要があります。どうもありがとう。 – PaulG

+2

@PaulG、大体の経験則として、クラスがIDisposableを実装するときはいつでも、できるだけ早くそれを廃棄すべきです。読者の場合は、データベースサーバーのリソースを閉じたり廃棄したりするまで、データベースサーバーのリソースを集めて、処理が完了次第、処分します。今はMySQLを使用しているので、リソースの使用状況はわかりませんが、OracleやSQL ServerなどのサーバーベースのDBMSシステムではこれが当てはまります。 –

2

私は一般的にアダプタを使用しているので、読者の詳細には錆びていますが、あなたは正しい道にいると思います。

コードには、ExecuteReaderを呼び出すたびに新しいデータリーダーが生成されるという点があります。変数名を再利用している可能性がありますが、既存のリーダへの参照は破棄され、呼び出しごとに新しいものに置き換えられます。つまり、新しいReaderを取得する前に、以前のリーダーを閉じてからExecuteReaderを使用してください。