• 说说IUnitOfWork~方法完整性与统一提交不冲突


    回到目录

    第一讲 认识IUnitOfWork,为什么要出现IUnitOfWork接口
    第二讲 Linq to Sql与EntityFrameworks中的SubmtChanges()发生了什么事
    第三讲 方法完整性与统一提交不冲突
    第四讲 DbContext对象的创建应该向BLL层公开
    第五讲 我的IUnitOfWork+Repository架构
     

        在一个方法中,它一般会做一件事情,这样的方法在功能上比较清晰,在职责上也很单一(这里的单一是褒义的,呵呵),而它所做的这件事,从头到尾会把它做完,不会做到一半的功能,这属于功能上的不完整,这不是我们推荐的。

    项目中的代码:

    完整的提交方法:

            protected virtual void SaveChanges()
            {
                if (!iUnitWork.IsNotSubmit)
                    iUnitWork.Save();
            }

    完整的插入方法:

           public virtual void Add(TEntity item)
            {
                _db.Entry<TEntity>(item);
                _db.Set<TEntity>().Add(item);
                this.SaveChanges();
            }

    上面代码是EF实现的插入,很完善,将实现添加到实体集合,并使用SaveChanges()提交到数据库,一个完善的数据插入流程完成,但一个问题来了如果我们的

    业务操作不只是插入一张表,还有更新另一张表,怎么去实现呢?

           public virtual void Modify(TEntity item)
            {
                _db.Set<TEntity>().Attach(item);
                _db.Entry(item).State = EntityState.Modified;
                this.SaveChanges();
            }

    上面为完整的更新动作是上面的代码,现在有一个假设:

    UserRepository类有方法Add,ProductRepository类有方法Modify,这时,这两个方法进行组织,代码可能是这样:

    ...code

    userRepository.Add(user);

    userRepository.Modify(product);

    ...code

          事实上,上面的代码所执行的过程为:先插入用户表,提交到SQL数据库,再更新产品表,再提交到SQL数据库,这时由于提交两次,SQL端会产生两个连接池,而如果两个方法使用了TransactionScope事务块,并且SQL服务器与WWW服务器在不同的电脑上,会触发多于的分布式事务(这是可以避免的),而我们知道,windows的MSDTC(分布式事务)服务是最不靠谱的

    如何解决这种情况呢,难道方法不该完整吗?

    什么事情都有解决的办法,方法的完整性在系统设计上是没有问题的,但有时,对于一个工作单元中有多个方法时,我们需要把这种完整性升级,将多个方法提升为一个整体,即多个方法的完整性问题,解决这个问题的关键在于,你的数据上下文是否为一个,你的submitChanges方法是否为一个。

    IUnitWork崭新的接口规范

        /// <summary>
        /// 工作单元
        /// 提供一个保存方法,它可以对调用层公开,为了减少连库次数
        /// </summary>
        public interface IUnitOfWork
        {
            /// <summary>
            /// 将操作提交到数据库,
            /// </summary>
            void Save();
            /// <summary>
            /// 是否不提交到数据库,这只是在具体的repository类中的SaveChanges方法里用到的
            /// 默认为false,即默认为提交到数据库
            /// </summary>
            /// <returns></returns>
            bool IsNotSubmit { get; set; }
        }
    
        /// <summary>
        /// 工作单元
        /// 对泛型类型的支持
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public interface IUnitWork<T> : IUnitOfWork where T : class { }

    看了上面的接口,不用我说,大家也知道其中的含义了,Save()为数据上下文提交,而IsNotSubmit表示是否要提交到数据库,我们都知道bool类型对象的默认

    值不false,所以,默认情况下,Add,Modify这些方法的提交动作都是true,即被提交到数据库。

    我们优化这时上面add与modify的方法如下:

    Domain.Core.IUnitOfWork _iUnitWork = new backgroundEntities();
     _iUnitWork.IsNotSubmit=true;
    userRepository(user);
    productRepository(product); 
    _iUnitWork.Save();

    OK, 上面的代码所产生的效果就是,将两条SQL语句发到SQL端 ,使用一个SQL连接池,不产生MSDTC服务。

    回到目录

  • 相关阅读:
    node的安装与配置
    linux下查看是否安装某个软件
    怎么把apk文件部署在云服务器上
    github怎么搜索!!!
    node.js搭建本地服务器的两种方式(anywhere和http-server)
    js中迭代方法
    yarn和npm的区别
    总结一下测试工程师学习的博客和网站
    我的周记1——”云想衣裳花想容"
    2019/11/22 再聊职业规划——5年后,你想成为怎样的人?
  • 原文地址:https://www.cnblogs.com/lori/p/2966897.html
Copyright © 2020-2023  润新知