自研ORM框架實現工作單元模式

2022-12-27 15:01:05

平時我們使用事務,需要顯示的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 "工作單元執行完成...";
        }