You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Dapper实现多数据库连接的方案合理性及非抽象类替代方式咨询

Dapper多数据库连接实现分析:合理性与无抽象类替代方案

一、当前抽象类实现的合理性

你当前基于抽象类BaseRepository的实现是合理的,核心优势包括:

  • 代码复用:将Dapper通用操作(如ExecuteAsync)统一封装在基类,避免每个业务Repository重复编写相同逻辑,符合DRY原则。
  • 多库适配清晰:结合[FromKeyedServices]注入指定Key的数据库连接,能在依赖注入容器中通过注册不同Key的IDbConnection实例,轻松实现多数据库的区分与切换,适配多库场景需求。
  • 异常处理统一:基类中统一捕获并包装异常,上层Repository无需重复处理通用异常逻辑,降低代码冗余。

可以优化的小细节:

  • 异常消息中的"retrieving the company"与ExecuteAsync操作不匹配,建议改为通用描述(如"执行SQL操作时出错")。
  • 若子类需要直接操作数据库连接,可将_dbConnection的访问修饰符改为protected。

二、无需抽象类的替代实现方案

方案1:IDbConnection扩展方法

将通用Dapper操作封装为IDbConnection的扩展方法,业务Repository直接注入指定连接并调用扩展方法:

// 扩展方法类
public static class DapperExtensions
{
    public static async Task<int> ExecuteWithExceptionHandleAsync(this IDbConnection dbConnection, 
        string sql, object? param = null, IDbTransaction? transaction = null, 
        int? commandTimeout = null, CommandType? commandType = null)
    {
        try
        {
            return await dbConnection.ExecuteAsync(sql, param, transaction, commandTimeout, commandType)
                .ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            throw new Exception("执行SQL操作时出错", ex);
        }
    }
}

// 业务Repository
public class PRepository
{
    private readonly IDbConnection _dbConnection;

    public PRepository([FromKeyedServices(DbConnectionKeys.PCMRead)] IDbConnection dbConnection)
    {
        _dbConnection = dbConnection;
    }

    public async Task<int> UpdateProductAsync(string sql, object productParams)
    {
        return await _dbConnection.ExecuteWithExceptionHandleAsync(sql, productParams);
    }
}

优势:无需继承关系,灵活性更高,Repository可按需选择是否使用扩展方法,避免强耦合。

方案2:组合式Dapper操作服务

创建独立的Dapper操作服务类,通过组合方式在Repository中复用通用逻辑:

// 操作服务接口与实现
public interface IDapperOperationService
{
    Task<int> ExecuteAsync(IDbConnection dbConnection, string sql, object? param = null, 
        IDbTransaction? transaction = null, int? commandTimeout = null, CommandType? commandType = null);
}

public class DapperOperationService : IDapperOperationService
{
    public async Task<int> ExecuteAsync(IDbConnection dbConnection, string sql, object? param = null, 
        IDbTransaction? transaction = null, int? commandTimeout = null, CommandType? commandType = null)
    {
        try
        {
            return await dbConnection.ExecuteAsync(sql, param, transaction, commandTimeout, commandType)
                .ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            throw new Exception("执行SQL操作时出错", ex);
        }
    }
}

// 业务Repository
public class PRepository
{
    private readonly IDbConnection _dbConnection;
    private readonly IDapperOperationService _dapperService;

    public PRepository([FromKeyedServices(DbConnectionKeys.PCMRead)] IDbConnection dbConnection,
        IDapperOperationService dapperService)
    {
        _dbConnection = dbConnection;
        _dapperService = dapperService;
    }

    public async Task<int> DeleteProductAsync(string sql, object deleteParams)
    {
        return await _dapperService.ExecuteAsync(_dbConnection, sql, deleteParams);
    }
}

优势:遵循"组合优先于继承"的设计原则,降低类之间的耦合度,Dapper操作服务可单独进行单元测试,Repository职责更单一。

方案3:Repository直接封装Dapper操作

若业务Repository的操作差异较大,无需统一通用逻辑,可直接在Repository中注入连接并编写Dapper操作:

public class PRepository
{
    private readonly IDbConnection _dbConnection;

    public PRepository([FromKeyedServices(DbConnectionKeys.PCMRead)] IDbConnection dbConnection)
    {
        _dbConnection = dbConnection;
    }

    public async Task<int> AddProductAsync(string sql, object productParams)
    {
        try
        {
            return await _dbConnection.ExecuteAsync(sql, productParams)
                .ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            throw new Exception("添加产品时出错", ex);
        }
    }
}

优势:无额外抽象层,实现简单直接,适合每个Repository有独特业务逻辑的场景。

内容的提问来源于stack exchange,提问作者user2797910

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 03:12:45