2

我需要一些帮助来更好地理解 Dapper 如何处理数据库连接,以及为什么没有正确处理数据库连接。我已经围绕不同的可能情况进行了编码。在我的代码中,我正在检查 _connection 是否为空,并相应地创建一个新连接。在处理请求时,我发现有时连接处于打开状态,而有时我发现对象中缺少连接字符串(使其无法使用,但未将其设置为 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 Repository 如下,带有一个示例方法 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 回答