2009-05-26 21 views
6

SQL接続のベストプラクティスは何ですか?SQL Server接続の管理

現在、私は次のように使用しています:

using (SqlConnection sqlConn = new SqlConnection(CONNECTIONSTRING)) 
{ 
    sqlConn.Open(); 
    // DB CODE GOES HERE 
} 

私は、これはSQL接続を行うための非常に効果的な方法であることを読んだことがあります。デフォルトではSQLプールはアクティブなので、usingコードの終了時にSqlConnectionオブジェクトがクローズされて破棄されても、実際のDBへの接続はSQL接続プールに置かれます。これについて間違っていますか?

答えて

13

それがほとんどです。考慮すべき追加ポイント:

  • 接続文字列はどこにありますか?あなたはその場所にハードコードされたものを望んでおらず、それを保護する必要があるかもしれません。
  • あなたは、多くの場合、あなたが接続を開くためにできるだけ長く待ちたいあなたが本当に接続(SqlCommandSqlParameterDataSetSqlDataAdapter)を使用する前にも作成するには、他のオブジェクトを持っている、と。完全なパターンはそれを説明する必要があります。
  • データベースアクセスが自分自身のデータレイヤークラスまたはアセンブリに強制されていることを確認する必要があります。したがって、一般的なことはプライベート関数呼び出しとしてこれを表現することです:

その後、

private static string connectionString = "load from encrypted config file"; 
private SqlConnection getConnection() 
{ 
    return new SqlConnection(connectionString); 
} 

そして、このようなあなたのサンプルを書く:サンプルは、あなたのデータアクセスクラスにのみ存在することができること

using (SqlConnection sqlConn = getConnection()) 
{ 
    // create command and add parameters 

    // open the connection 
    sqlConn.Open(); 

    // run the command 
} 

。別の方法として、internalとマークし、データレイヤーをアセンブリ全体に広げることができます。主なことは、データベースコードの明確な分離が厳密に強制されることです。私もcncmdオブジェクトの作成「スタック」することができたので、ネストを削減し、唯一のスコープのブロックを作成

public IEnumerable<IDataRecord> GetSomeData(string filter) 
{ 
    string sql = "SELECT * FROM [SomeTable] WHERE [SomeColumn] LIKE @Filter + '%'"; 

    using (SqlConnection cn = getConnection()) 
    using (SqlCommand cmd = new SqlCommand(sql, cn)) 
    { 
     cmd.Parameters.Add("@Filter", SqlDbType.NVarChar, 255).Value = filter; 
     cn.Open(); 

     using (IDataReader rdr = cmd.ExecuteReader()) 
     { 
      while (rdr.Read()) 
      { 
       yield return (IDataRecord)rdr; 
      } 
     } 
    } 
} 

お知らせ:

実際の実装は次のようになります。

最後に、この特定のサンプルでyield returnコードを使用することについての注意の言葉。メソッドを呼び出してDataBindingやその他の使用をすぐに完了しないと、接続を長時間開いたままにすることができます。これの例は、ASP.NETページのLoadイベントでデータソースを設定することです。実際のデータ・バインディング・イベントは、後で接続が必要以上に長く開いてしまうまで発生しないため、

+0

ポイント1:私は、接続文字列をapp/web.configのセクションに保存します。 ポイント2:これは何か心配する必要がありますか?私は通常、SqlConnectionを行い、それを開いてから、sqlCommandを作成し、そこから取得します。 ポイント3:私たちはすべてのDBアクセスをクラスlibから行います。私はコアアプリケーションからDBアクセスを行うのが好きではありません。 getConnectionメソッドを作成するのは私の価値がありますか? – Neale

+0

すべてのdbアクセスにクラスlibを使用するので、接続文字列をアプリケーション全体にグローバルになる.configファイルではなく、クラスlibの.configファイルの一部にするのは簡単です。これは、きれいなデータレイヤの分離を実行するのに十分なはずですが、同時にメソッドをパブリックにする理由もありません。それはポイント1と3を扱っているはずです。ポイント2については、余分な1行か2行のために何かを傷つけることはないでしょうが、どちらも助けていません。私は別の理由でそれをやりたければ編集しています。 –

+0

あなたの 'yield return'の例は、やや誤解を招く例です。 'yield return'の周りに構築された関数は' IEnumerator'の 'MoveNext()'の最初の呼び出しまでexecutigを開始しません。したがって、たとえ関数を呼び出しても、結果を反復処理するまで接続は開かれません。 –

1

ご使用の理解は正しいものであり、その使用方法が推奨されています。コード内でcloseも呼び出すことができます。

+1

ありがとうございました。私がそれを理解する方法は、 "使用"が終了し、SqlConnection.Dispose()を呼び出すときです。最終的にSqlConnection.Close()を呼び出します。 – Neale

+0

「使用する」ことについての理解も正しいです。 –

+0

@Neale - そうであれば、SqlConnection.Dispose()は必要に応じてCloseを呼び出します。接続がすでに閉じられている場合、ハンドルをado.netプロバイダーに戻し、プールに入れたり、実際に閉じることができます。 –

2

マイクロソフトのPatterns and Practicesライブラリは、データベース接続を処理する優れた方法です。ライブラリは、接続を開く際に必要となるメカニズムの大部分をカプセル化し、それによってあなたの人生が楽になります。

0

他も開けて、早めに閉じる。

データベースを呼び出す前にステップがなくなるまで接続をオープンしないでください。完了したらすぐに接続を閉じてください。

関連する問題