平時我們使用事務,需要顯示的Try Catch 並且開啟事務 提交事務 異常回滾事務 三步驟,使用工作單元后則只需要Commit。
1.介面定義
1 /// <summary> 2 /// 工作單元介面類 3 /// </summary> 4 public interface IUnitOfWork : IDisposable 5 { 6 /// <summary> 7 /// 是否提交 8 /// </summary> 9 bool IsCommit { get; } 10 11 /// <summary> 12 /// 資料庫上下文 13 /// </summary> 14 IDbContext Db { get; } 15 16 /// <summary> 17 /// 提交 18 /// </summary> 19 /// <returns></returns> 20 bool Commit(); 21 }
2.介面實現
1 /// <summary> 2 /// 工作單元實現類 3 /// </summary> 4 public class UnitOfWork : IUnitOfWork 5 { 6 /// <summary> 7 /// 釋放 8 /// </summary> 9 private bool disposed = false; 10 11 /// <summary> 12 /// 是否提交 13 /// </summary> 14 public bool IsCommit { get; private set; } 15 16 /// <summary> 17 /// 資料庫上下文 18 /// </summary> 19 public IDbContext Db { get; } 20 21 /// <summary> 22 /// 構造方法 23 /// </summary> 24 /// <param name="db">資料庫上下文</param> 25 public UnitOfWork(IDbContext db) 26 { 27 this.Db = db; 28 this.Db.BeginTranAsync().Wait(); 29 } 30 31 /// <summary> 32 /// 提交 33 /// </summary> 34 /// <returns></returns> 35 public bool Commit() 36 { 37 if (!IsCommit) 38 { 39 this.Db.CommitTranAsync().Wait(); 40 IsCommit = true; 41 } 42 return IsCommit; 43 } 44 45 /// <summary> 46 /// 釋放 47 /// </summary> 48 public void Dispose() 49 { 50 Dispose(true); 51 GC.SuppressFinalize(this); 52 } 53 54 /// <summary> 55 /// 釋放 56 /// </summary> 57 /// <param name="disposing">釋放標記</param> 58 protected virtual void Dispose(bool disposing) 59 { 60 if (!this.disposed) 61 { 62 if (disposing) 63 { 64 if (!IsCommit) 65 { 66 this.Db.RollbackTranAsync().Wait(); 67 } 68 } 69 disposed = true; 70 } 71 } 72 73 /// <summary> 74 /// 解構函式 75 /// </summary> 76 ~UnitOfWork() 77 { 78 Dispose(false); 79 } 80 }
3.使用方式
1.註冊服務
1 // Add DbContext Service 2 builder.Services.AddFastDbContext(); 3 // Add UnitOfWork Service 4 builder.Services.AddFastUnitOfWork();
2.構造方法注入 UnitOfWork 物件使用時 無需顯示using 當發生異常時會自動呼叫 Dispose 方法
/// <summary> /// 構造方法 /// </summary> /// <param name="logger"></param> public ValuesController(ILogger<ValuesController> logger,IUnitOfWork unitOfWork) { this.logger = logger; this.unitOfWork = unitOfWork; } [HttpGet] public async Task<string> TestUnitOfWork() { var result1 = await unitOfWork.Db.Insert(new Category() { CategoryName = "類別3" }).ExceuteAsync(); var result2 = await unitOfWork.Db.Insert(new Product() { ProductCode = "測試工作單元_111", }).ExceuteAsync(); unitOfWork.Commit(); return "工作單元執行完成..."; }