參考SqlSugar的官網文件,我自己封裝了一個支援多資料庫的UnitOfWork 的 SqlSugar 封裝類,直接使用SqlSugar的倉儲操作
如下:
/// <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; } }