2

Dapper が DB 接続を処理する方法と、DB 接続が適切に破棄されない理由を理解する助けが必要です。考えられるさまざまなケースをコーディングしました。私のコードでは、_connection が null かどうかを確認し、それに応じて新しい接続を作成しています。リクエストを進めると、接続が開いたままになっている場合があり、オブジェクトに接続文字列が欠落している場合があります(使用できなくなりますが、NULL に設定されません)。私はこれらのケースをそれに応じて処理していますが、クライアント コードが明示的にusing を実装しているにもかかわらず、接続がこれらのさまざまな状態を持ち、破棄されない理由を理解したいと思います。コードをラップするステートメント。それはADO.netの接続の処理ですか、Dapperの副作用ですか、それとも私のコードの問題ですか?

接続管理コード

public class DatabaseContext : IDatabaseContext 
{
    private readonly string _connectionString;

    private DbConnection _connection;


    public DatabaseContext(string connectionString)
    {
        _connectionString = connectionString;

    }

    public IDbConnection Connection
    {
        get
        {

            if (_connection == null)
                _connection = new SqlConnection(_connectionString);

            if (string.IsNullOrEmpty(_connection.ConnectionString))
                _connection.ConnectionString = _connectionString;

            if (_connection.State != ConnectionState.Open)
                _connection.Open();

            return _connection;
        }
    }
}

クライアントコード

public IEnumerable<PostSearResults> Search(SearchPostsBy searchPostsBy)
{
    DynamicParameters param;
    var sql = GetSearchSql(searchPostsBy,out param);//Gets SQL 

    using (var connection = _databaseContext.Connection)
    {
        var posts = connection.Query<PostSearResults>(sql, param);
        return posts.ToList();
    }
}
4

1 に答える 1

2

私は Web アプリケーションでも Dapper を使用しており、あなたと同様の DapperContext を実装していますが、次のようにクラスに IDispose を実装しています。

    #region IDisposable

    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                if (transaction != null)
                { transaction.Dispose(); }
                if (cn != null)
                { cn.Dispose(); }
            }
        }
        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    #endregion

私のバージョンの Dapper は、呼び出しを行ったときに閉じている場合は接続を開き、呼び出しを行ったときに接続が開いている場合は、クエリを実行した後に閉じます。Dapper はクエリを実行し、接続を開いたままにします。

DI も使用しているため、DapperContext の有効期間は DI コンテナーによって管理されているため、Web 要求コンテキストが終了して破棄されたときに破棄されます。私のDapperリポジトリは次のようなもので、サンプルメソッドGetPEを使用しています

private readonly IDbConnection context;
private readonly DapperContext dapperContext;

public SFRepository(DapperContext dbContext)
{
    dapperContext = dbContext;
    context = dbContext.Connection;
}

public PEData GetPE(int peID)
{
     PEData rec = context.Query<PEData>("SELECT * FROM PEDATA WHERE ID= @ID", new { ID = peID }).FirstOrDefault();

     return rec;
}

非常に安定しており、奇妙な動作はありません。

于 2015-06-10T12:31:49.357 に答える