zoukankan      html  css  js  c++  java
  • 项目架构开发:数据访问层之UnitOfWork

    接上文 项目架构开发:数据访问层之IQuery

    本章我们继续IUnitOfWork的开发,从之前的IRepository接口中就可以看出,我们并没有处理单元事务,

    数据CUD每次都是立即执行的,这样有一些不好的地方,比如数据访问次数会增多,一笔数据的完整性无法保证

    比如:批量新增2条记录,只有一条成功,这样的情况就应该Rollback;可能有人已经想到用数据库自带的事务保证完整性

    虽然是可以,但是这样就不可避免地在业务层耦合SqlTransaction,我不想这种情况出现;

    所以我们用windows自带的分布式事务TransactionScope来实现,TransactionScope可以实现多个数据库的事务锁,这点就比SqlTransaction强一些

    当然我了解到分布式事务是不一般的复杂的,那些更好的处理方式我还没有掌握,所以先这么写吧,有这方面经验的朋友欢迎提建议

    IUnitOfWork.cs

    1     public interface IUnitOfWork<T> where T : class
    2     {
    3         void RegisterAdd(T entity, Action callback);
    4         void RegisterUpdate(T entity, Action callback);
    5         void RegisterDelete(T entity, Action callback);
    6         void Commit();
    7     }

    注册新增操作:RegisterAdd

    注册更新操作:RegisterUpdate

    注册修改操作:RegisterDelete

    提交数据:Commit

    工作单元的实现

     1 public class UnitOfWork<T> : IUnitOfWork<T> where T : class
     2     {
     3         private Dictionary<T, Action> addEntities;
     4         private Dictionary<T, Action> updateEntities;
     5         private Dictionary<T, Action> deleteEntities;
     6 
     7         public UnitOfWork()
     8         {
     9             addEntities = new Dictionary<T, Action>();
    10             updateEntities = new Dictionary<T, Action>();
    11             deleteEntities = new Dictionary<T, Action>();
    12         }
    13 
    14         public void RegisterAdd(T entity, Action callback)
    15         {
    16             this.addEntities.Add(entity, callback);
    17         }
    18 
    19         public void RegisterUpdate(T entity, Action callback)
    20         {
    21             this.updateEntities.Add(entity, callback);
    22         }
    23 
    24         public void RegisterDelete(T entity, Action callback)
    25         {
    26             this.deleteEntities.Add(entity, callback);
    27         }
    28 
    29         public void Commit()
    30         {
    31             using (TransactionScope scope = new TransactionScope())
    32             {
    33                 foreach (var entity in deleteEntities.Keys)
    34                 {
    35                     this.deleteEntities[entity]();
    36                 }
    37 
    38                 foreach (var entity in updateEntities.Keys)
    39                 {
    40                     this.updateEntities[entity]();
    41                 }
    42 
    43                 foreach (var entity in addEntities.Keys)
    44                 {
    45                     this.addEntities[entity]();
    46                 }
    47 
    48                 scope.Complete();
    49             }
    50         }
    51     }

    这里我们用了Action,这个是无返回值委托方法,如果大家需要返回值可以用Func

    实现我们还是用DapperRepository,修改一下。在新增方法中注册数据持久化方法

    好了,现在我们来看看测试结果

    测试工作单元

    还是用原来那个DapperRepositoryTest

    我们修改一下实现过程:

    单个新增

     

    批量新增

    运行结果

     我们把表结构改一下,名称改成不能为null

    AddBatch也要修改,正常的执行结果一个是抛出异常

     1         [TestMethod]
     2         public void AddBatch()
     3         {
     4             try
     5             {
     6                 var loginUser1 = new LoginUser()
     7                 {
     8                     Id = Guid.NewGuid(),
     9                     LoginName = "lanxiaoke-" + Guid.NewGuid().ToString(),
    10                     Password = "mima1987",
    11                     IsEnabled = 1,
    12                     CreateTime = DateTime.Now
    13                 };
    14 
    15                 var loginUser2 = new LoginUser()
    16                 {
    17                     Id = Guid.NewGuid(),
    18                     //LoginName = "lanxiaoke-" + Guid.NewGuid().ToString(),
    19                     Password = "mima1987",
    20                     IsEnabled = 1,
    21                     CreateTime = DateTime.Now
    22                 };
    23 
    24                 var list = new List<LoginUser>();
    25                 list.Add(loginUser1);
    26                 list.Add(loginUser2);
    27 
    28                 repository.AddBatch(list);
    29                 unitOfWork.Commit();
    30             }
    31             catch (Exception ex)
    32             {
    33                 var err = ex.Message;
    34             }
    35 
    36             //long count = repository.Count(t => t.LoginName.In(new string[] { loginUser1.LoginName, loginUser2.LoginName }));
    37 
    38             //Assert.AreEqual(true, count >0);
    39         }

    运行看看

    如期运行,到这里,工作单元就讲完了

    完整项目架构

    我们来看看完整的数据访问层架构

    整个数据访问层就讲完了,虽然有些简陋,但是基本功能都有了

    项目架构开发系列

  • 相关阅读:
    矩阵
    手机APP和WAP版的区别
    学习的方法
    ASP.Net中jQuery控制div弹出框效果
    SQL SERVER字符串前加N转换为Unicode编码
    塞尔维亚国家简称编码
    VS2019项目模板中没有[ASP.NET空网站]的解决方案
    Scopus论文数据爬虫
    采集科研文献和数据,我告诉你一个能自动采集的黑科技
    CiteSpace入门教程
  • 原文地址:https://www.cnblogs.com/lanxiaoke/p/6504443.html
Copyright © 2011-2022 走看看