web-dev-qa-db-ja.com

クラスに共通のデータベース接続を配置する場所

私はいくつかのクラス(リポジトリ)を持っています。これらのクラスは、いくつかのオブジェクトをデータベースに保存したり、データベースから取得したりするタスクを実行します。それらすべてが1つのデータベースへの接続を確立する必要があります。

各クラスでConnectionStringSqlConnectionを再定義しないように、オープン接続をそれらに渡すことを考えました。次に、その接続を定義/オープンしてクラスに渡すのに最適な場所/時間はいつ/どこですか?

この共通のリソースにアクセスするためのより良いアプローチ/パターンはありますか?

11
Ahmad

オープン接続を各クラスに渡すことは、おそらく最良のアイデアではありません。 データベース接続の作成-クエリごとに1回実行しますか?

開いている接続をリポジトリに渡すのではなく、実行するクエリごとに接続を開いたり閉じたりすることをお勧めします。

あなたはあなたの接続を管理するのを助けるためにこのような何かを試すことができます。

public class Repository
{
    private readonly string _connectionString;

    public Repository()
    {
        _connectionString = ConfigurationManager.ConnectionStrings["connString"].ConnectionString
    }

    protected SqlConnection GetConnection()
    {
         return new SqlConnection(_connectionString);
    }


}

public sealed class UserRespository : Repository
{

    public User GetUsers()
    {
        using (var connection = GetConnection())
        {
            using (var commnad = new SqlCommand("SqlQuery", connection))
            {
                //Execute Query
                //Return results
            }
        }
    }
}
10
Gibson

開いた接続を持ち、クラス間でそれを渡すことは一般に悪い考えです。確かに、接続を開くことはパフォーマンスに大きな影響を与えますが、すでに開かれている接続を再利用することで、接続プールによってすでに処理されています。ただし、特にマルチスレッドコードでは、これがメソッドへの接続を割り当てるため、可能な限り常にconnection.Open()を呼び出すまで待機します(データベースへの必要なオープン接続の数が大幅に増加します)。

クラスをできるだけ汎用的にするには、IDbConnectionでメソッドを公開する基本クラスを用意することをお勧めします。リポジトリには、より汎用的な実装が含まれます。

internal abstract class Repository
{
    private static readonly string ConnectionString = ConfigurationManager.ConnectionStrings["myconnectionstring"].ConnectionString;

    protected IDbConnection GetConnection()
    {
        return new SqlConnection(ConnectionString);
    }
}

public class MyRepository : Repository
{
    public IEnumerable<object> Get()
    {
        using (var connection = GetConnection())
        {
            connection.Open();

            ...
        }
    } 
}
5
Richard Jansson