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

news/2024/7/8 13:09:00 标签: 数据库

回到目录

第一讲 认识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服务。

回到目录


http://www.niftyadmin.cn/n/1595508.html

相关文章

CSS预处理器-Less

less 认识 Less是一个 CSS预处理器&#xff0c; Less文件后缀为.less浏览器不识别less文件&#xff0c;所以在VScode里使用Easy Less插件自动生成css文件 优点&#xff1a; css逻辑更加清晰免去了繁琐的计算&#xff08;直接写计算式就可&#xff09; 注释 // 单行注释 C…

运维博客集

1. http://blog.kn126.com/ 运维世界一个运维初学者的学习历程Linux/CentOS/Ubuntu/FreeBSD 服务器教程Windows Server 2003/2008 服务器教程 2.云维科技 http://kicklinux.com/ 首页集群和高可用NOSQL云计算虚拟化自动化运维系统基础运维服务 3.南http://alsww.blog.51cto.co…

IO 常用IO操作类继承结构 及简单简介

IO字符流Reader(源)BufferedReaderLineNumberReaderInputStreamReaderFileReader(字节流通向字符流的桥梁)StringReader Writer(目的)BufferedWriter OutputStreamWriterFileWriter(字符流通向字节流的桥梁)StringWriter PrintWriter 字节流InputStream(源)FileInputStream…

JS循环练习-简易银行ATM

需求&#xff1a; 用户可以选择存钱、取钱、查看余额和退出功能 分析&#xff1a; 1. 弹窗显示功能&#xff0c;将prompt写到循环里 2. 只有用户点击退出时才能跳出循环 3. ATM功能可以使用开关语句 效果图&#xff1a; 代码示例&#xff1a; <!DOCTYPE html> <…

Websphere MQ 7.0.0 For Linux版安装

为什么80%的码农都做不了架构师&#xff1f;>>> 将压缩包上传至指定目录&#xff0c;比如&#xff1a;/home/hqh/MQ7下面。 [rootlocalhost hqh]# cd MQ7 [rootlocalhost MQ7]# ls CZ50AML.tar.gz 修改权限 [rootlocalhost MQ7]# chmod 755 CZ* 解压 [rootl…

移动适配-vw/wh

vw/vh 是相对单位 vw&#xff1a;viewport width 1vw 1/100视口宽度 vh&#xff1a;viewport height 1vh 1/100视口高度 vw单位尺寸 1.确定设计稿对应的vw尺寸 &#xff08;1/100视口宽度&#xff09; 查看设计稿宽度 → 确定参考设备宽度 (视口宽度) → 确定vw尺寸 &a…

每天学点GDB 4

本节侧重于如何用各种方法查看变量的值。 #include <stdlib.h> #include <stdio.h>void show_slogan(char* slogan); int counter; char* welcome_msg "you are welcome!"; int main(int argc, char** argv) {int i 0;counter 0;show_slogan(welcome_…

JS循环-for循环嵌套

打印5行5列星星 效果图 代码 // 打印出5行5列的星星for(i 1 ; i < 5 ; i ) {// 外层控制打印行for(j 1 ; j < 5 ; j ) {// 内层控制每行打印几个document.write(⭐)}document.write(<br>)}打印侧三角 效果图 代码 for(i 1 ; i < 5 ; i ) {for(j 1 ; j &…