前提条件

TransactionScope类需要引用System.Transactions;

数据库环境及需求

现在假设有两个表如图:

                                     

           表TA                                                                                  表TB

现有数据:                                            

现在的需求是:每往TA中插入一条数据,就更新TB的第一行,值为表TA的所有行的Age的平均值

可以看到表TB的Remark长度仅仅为2,待会利用这个制造错误

 

当不使用TransactionScope时:

 using (EFTestEntities db = new EFTestEntities()){//数据库TA原有2行,此时添加第3行var aEntity = new TA{Name = "a",Age = 20};db.TA.Add(aEntity);var listTA = db.TA.ToList();//此时list只有2行,新添加的没有读取到int totalAge = 0;listTA.ForEach(p => totalAge += p.Age);//获取表TB的第一行,并修改AvgAge值var bEntity = db.TB.First();bEntity.AvgAge = totalAge / listTA.Count;bEntity.Remark = "bb";db.SaveChanges();//结果是Tb的值没有变化}  

View Code

你认为是添加TA后没有db.SaveChanges();? 的确,添加这个之后,可以读取到新添加的值了,但是没有事务了,如:

using (EFTestEntities db = new EFTestEntities()){//数据库TA原有2行,此时添加第3行var aEntity = new TA{Name = "a",Age = 20};db.TA.Add(aEntity);db.SaveChanges();var listTA = db.TA.ToList();//此时list有3行了,新添加的可以被读取到int totalAge = 0;listTA.ForEach(p => totalAge += p.Age);//获取表TB的第一行,并修改AvgAge值var bEntity = db.TB.First();bEntity.AvgAge = totalAge / listTA.Count;bEntity.Remark = "bbc";//故意超出长度,制造错误
                db.SaveChanges();//结果是TA添加了新行,但是TB修改时出错导致修改失败。造成了数据不一致}  

View Code

结果是TA添加了新行,但是TB因为remark超出长度导致导致修改失败,此时TB的数据是错的。

怎样可以避免这个问题?答案就是用事务。

使用TransactionScope:

using (EFTestEntities db = new EFTestEntities()){using (TransactionScope ts = new TransactionScope()){//数据库TA原有2行,此时添加第3行var aEntity = new TA{Name = "a",Age = 20};db.TA.Add(aEntity);db.SaveChanges();//重点,必须要db.SaveChanges(),然后下面才能获取到新添加的行var listTA = db.TA.ToList();//此时list有3行了,新添加的可以被读取到int totalAge = 0;listTA.ForEach(p => totalAge += p.Age);//获取表TB的第一行,并修改AvgAge值var bEntity = db.TB.First();bEntity.AvgAge = totalAge / listTA.Count;bEntity.Remark = "bbc";//故意超出长度,制造错误db.SaveChanges(); //执行到此处程序报错
ts.Complete();//事务提交未执行//结果是自动回滚,相当于此次没有对数据库做任何操作。保持了数据一致性
                }}

View Code

下面给出正确的示例,实现以上需求:

using (EFTestEntities db = new EFTestEntities()){using (TransactionScope ts = new TransactionScope()){//数据库TA原有2行,此时添加第3行var aEntity = new TA{Name = "a",Age = 20};db.TA.Add(aEntity);db.SaveChanges();//重点,必须要db.SaveChanges(),然后下面才能获取到新添加的行var listTA = db.TA.ToList();//此时list有3行了,新添加的可以被读取到int totalAge = 0;listTA.ForEach(p => totalAge += p.Age);//获取表TB的第一行,并修改AvgAge值var bEntity = db.TB.First();bEntity.AvgAge = totalAge / listTA.Count;bEntity.Remark = "bb";//数据符合规范db.SaveChanges(); //保存
ts.Complete();//提交事务//结果是执行成功,TA多一条数据,同时TB的值也变了
                }}

View Code

一切都nice了!

转载于:https://www.cnblogs.com/dengshaojun/p/5761013.html

EF中关于TransactionScope的使用相关推荐

  1. 关于EF中ApplyCurrentValues和ApplyOriginalValues区别

    关于EF中ApplyCurrentValues和ApplyOriginalValues区别:两者都是编辑数据时使用. //         // 摘要:         //     将 System ...

  2. 数据库在EF中创建模型

    数据库在EF中创建模型,最简单的理解就是把数据库的字段以及关系映射到项目中,在项目中通过EF框架和LINQ语句直接对数据库数据进行增删改查.下边手把手教你建立模型. 1.建立一个项目,添加新项目,选择 ...

  3. 在EF中使用SQL执行简单高效的增删查操作

    随着平台数据的积累,对于数据访问的速度要求愈来愈高.优化后台访问性能,将是之后的一个重点任务. 但是,后台在项目开发初期采用的是Abp(Lite DDD)框架,集成EnityFramework.因为之 ...

  4. EF中加载实体的方式

    EF中的查询执行时机: 1. foreach进行枚举 2. ToArray.ToList.ToDictionary 3. Linq的一些操作,如First.Any 4. DbSet上的Load操作.D ...

  5. EF中三大开发模式之DB First,Model First,Code First以及在Production Environment中的抉择

    一:ef中的三种开发方式 1. db first... db放在第一位,在我们开发之前必须要有完整的database,实际开发中用到最多的... <1> DBset集合的单复数... db ...

  6. CodeFirst EF中导航属性的个人理解

    >导航属性: 01.个人理解就是Ef中的属性在实体数据表中不存在(先这么认为); 02.就是除了根据表中列映射出的属性 之外根据表与表之间的关系的关联属性.方便操作与之关联的表; 例如: 有 表 ...

  7. EF中的那些批量操作

    在使用EF的过程中,我们经常会遇到需要批量操作数据的场景,批量操作有的时候不仅能提高性能,比如使用SqlBulkCopy进入批量插入的时候,而且比较方便操作,提高效率.那么这篇文章就来总结EF中的那些 ...

  8. [转载]EF中的那些批量操作

    阅读目录 插入 更新 删除 在使用EF的过程中,我们经常会遇到需要批量操作数据的场景,批量操作有的时候不仅能提高性能,比如使用SqlBulkCopy进入批量插入的时候,而且比较方便操作,提高效率.那么 ...

  9. EF框架学习(5)---EF中的在线和离线场景

    EF中的持久性场景 使用EF实现实体持久化(保存)到数据库有两种情况:在线场景和离线场景. 1.在线场景 在线场景中,context是同一个上下文实例(从DbContext派生),检索和保存实体都通过 ...

最新文章

  1. 【摄像头】低照度和光圈
  2. 架构师课程之-haproxy专业级负载均衡软件权威讲解
  3. Code Generate of Power Designer[转]
  4. Python基础(三)深浅拷贝、函数、文件处理、三元运算、递归、冒泡排序
  5. Error Domain=NSURLErrorDomain Code=-999 The opera
  6. Http与WWW服务精解
  7. jsf教程_JSF范围教程– JSF / CDI会话范围
  8. php gps 坐标,php 计算gps坐标 距离
  9. 系统架构师学习笔记-数据通信与计算机网络(一)
  10. 漫画:程序员每天的6场战斗
  11. java app log4j 配置_Java-未加载log4j2配置
  12. MYSQL5.7---ONLY_FULL_GROUP_BY 异常处理
  13. linux mysql库文件路径设置_MySQL_linux修改mysql数据库文件的路径,mysql更改数据文件的存放路径 - phpStudy...
  14. 2012年8月 发散的安全焦点
  15. 配置网卡和修改ip地址
  16. 手机dpi修改工具_修改手机的分辨率,让你的手机更流畅
  17. 六字诀教你辨肾脏是否健康
  18. 核电站问题 解题报告
  19. huoshan_火山版 xl,xa,xg,xk 签名参数分析
  20. 85寸电视机长宽是多少

热门文章

  1. SELinux系列(十七)—awk命令使用详解
  2. 案例解析|政府信息化的BI建设应用
  3. 正确选择报表工具的十大标准
  4. windows 读写锁 python_用Python实现读写锁
  5. debug跳出循环_Java基础-第04章:循环结构「云图智联」
  6. 路由器下一跳地址怎么判断_路由器的功能及工作原理
  7. 3d建模电脑配置要求_专业3d动画建模需要什么配置 运行Blender的电脑配置推荐
  8. python网络爬虫学习笔记(一):网页基础
  9. 机器学习之方差与偏差(bias-variance)
  10. K-means++算法的学习笔记~