参考SqlSugar的官网文档,我自己封装了一个支持多数据库的UnitOfWork 的 SqlSugar 封装类,直接使用SqlSugar的仓储操作,如果需要其他对象,可以在BaseDbClient中自行添加
如下:
/// <summary> /// 数据库实例基类 /// </summary> public abstract class BaseDbClient { /// <summary> /// 获取数据库客户端实例。 /// </summary> public virtual SugarUnitOfWork UnitOfWorkCilent { get; } public virtual IAdo Ado { get; } public virtual AopProvider Aop { get; } /// <summary> /// 基类构造函数,初始化数据库客户端实例。 /// </summary> /// <param name="connectionString">数据库连接字符串。</param> /// <param name="dbType">数据库类型。</param> /// <param name="isTran">是否默认开启事务。</param> protected BaseDbClient(string connectionString, DbType dbType, bool isTran = false) { var db = new SqlSugarClient(new ConnectionConfig { ConnectionString = connectionString, DbType = dbType, IsAutoCloseConnection = true, InitKeyType = InitKeyType.Attribute }); UnitOfWorkCilent = db.CreateContext(isTran); Ado = db.Ado; Aop = db.Aop; } }
/// <summary> /// 多个数据源使用只需要写多个class 去继承BaseDbClient 即可,注意数据库类型 /// </summary> public class TestDb : BaseDbClient { public TestDb(string connectionString, DbType dbType, bool isTran = false) : base(connectionString, dbType, isTran) { } }
/// <summary> /// 泛型接口定义工作单元模式,用于管理仓储和事务 /// </summary> /// <typeparam name="TContext">工作单元所需的DbContext类型</typeparam> public interface IUnitOfWork<TContext> : IDisposable where TContext : BaseDbClient { /// <summary> /// Ado 操作 /// </summary> IAdo Ado { get; } AopProvider Aop { get; } /// <summary> /// 获取特定实体类型的仓储 /// </summary> ISimpleClient<TEntity> Repository<TEntity>() where TEntity : class, new(); /// <summary> /// 开始事务 /// </summary> void BeginTran(); /// <summary> /// 提交事务 /// </summary> void Commit(); void UnitOfWorkCommit(); /// <summary> /// 回滚事务 /// </summary> void Rollback(); } /// <summary> /// 实现工作单元模式的基本功能 /// </summary> /// <typeparam name="TContext">工作单元所需的DbContext类型</typeparam> public class UnitOfWork<TContext> : IUnitOfWork<TContext> where TContext : BaseDbClient { private bool _disposed; private TContext _context; LoggerHelper<TContext> _loggerHelper; /// <summary> /// 构造函数 /// </summary> /// <param name="context">工作单元所需的DbContext实例</param> public UnitOfWork(TContext context, LoggerHelper<TContext> loggerHelper) { _context = context; _loggerHelper = loggerHelper; _context.Aop.OnLogExecuting = (sql, pars) => { var logContent = sql + "\r\n" + context.Ado.Context.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)); _loggerHelper.Debug(logContent); // 使用公共日志记录工具 }; } public IAdo Ado { get => _context.Ado; } public AopProvider Aop { get => _context.Aop; } public ISimpleClient<TEntity> Repository<TEntity>() where TEntity : class, new() { return _context.UnitOfWorkCilent.GetRepository<TEntity>(); } /// <inheritdoc/> public void BeginTran() { Ado.BeginTran(); } /// <inheritdoc/> public void Commit() { Ado.CommitTran(); } public void UnitOfWorkCommit() { _context.UnitOfWorkCilent.Commit(); } /// <inheritdoc/> public void Rollback() { Ado.RollbackTran(); } /// <inheritdoc/> public void Dispose() { if (!_disposed) { Ado.Dispose(); _disposed = true; } GC.SuppressFinalize(this); } }
static void Main(string[] args) { LoggerHelper<TestDb> loggerHelper = new LoggerHelper<TestDb>(); //建议依赖注入 TestDb testDb = new TestDb("Server=.;Database=mdata;User Id=root;Password=root;", DbType.MySql); IUnitOfWork<TestDb> unitOfWork = new UnitOfWork<TestDb>(testDb, loggerHelper); //可以做多数据源同时crud var dt = unitOfWork.Ado.GetDataTable("select * from test"); var list = unitOfWork.Repository<Test>().GetList(); try { unitOfWork.BeginTran(); unitOfWork.Repository<Test>().Insert(new Test()); unitOfWork.Commit(); } catch (Exception ex) { unitOfWork.Rollback(); throw ex; } }