前提条件

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 =
};
db.TA.Add(aEntity); var listTA = db.TA.ToList();//此时list只有2行,新添加的没有读取到
int totalAge = ;
listTA.ForEach(p => totalAge += p.Age); //获取表TB的第一行,并修改AvgAge值
var bEntity = db.TB.First();
bEntity.AvgAge = totalAge / listTA.Count;
bEntity.Remark = "bb";
db.SaveChanges();
//结果是Tb的值没有变化
}

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

using (EFTestEntities db = new EFTestEntities())
{
//数据库TA原有2行,此时添加第3行
var aEntity = new TA
{
Name = "a",
Age =
};
db.TA.Add(aEntity);
db.SaveChanges(); var listTA = db.TA.ToList();//此时list有3行了,新添加的可以被读取到
int totalAge = ;
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修改时出错导致修改失败。造成了数据不一致
}

结果是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 =
};
db.TA.Add(aEntity);
db.SaveChanges();//重点,必须要db.SaveChanges(),然后下面才能获取到新添加的行 var listTA = db.TA.ToList();//此时list有3行了,新添加的可以被读取到
int totalAge = ;
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();//事务提交未执行
//结果是自动回滚,相当于此次没有对数据库做任何操作。保持了数据一致性
}
}

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

using (EFTestEntities db = new EFTestEntities())
{
using (TransactionScope ts = new TransactionScope())
{
//数据库TA原有2行,此时添加第3行
var aEntity = new TA
{
Name = "a",
Age =
};
db.TA.Add(aEntity);
db.SaveChanges();//重点,必须要db.SaveChanges(),然后下面才能获取到新添加的行 var listTA = db.TA.ToList();//此时list有3行了,新添加的可以被读取到
int totalAge = ;
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的值也变了
}
}

一切都nice了!

EF中关于TransactionScope的使用的更多相关文章

  1. EF 中事务的书写

    在EF 中怎么使用事务? 这个问题纠结了我好久,直到有人跟我一起讨论,我和同事一起讨论查资料. 查的好多资料都是使用 using (TransactionScope scope = new Trans ...

  2. EF中的transaction的使用范例

    注意一点: 在EF中使用事物后,对于一个新增的model,在saveChanges后,可以得到该实体的自增ID,但在提交事物之前, 该数据并没有真正的新增到DB中,但此时可以得到model新增的自增I ...

  3. 在EF中正确的使用事务

    1.EF中使用事务: using (TransactionScope tran = new TransactionScope()) { try { using(var _context = new D ...

  4. 1.【使用EF Code-First方式和Fluent API来探讨EF中的关系】

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/relationship-in-entity-framework-using-code-firs ...

  5. 2.EF中 Code-First 方式的数据库迁移

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/code-first-migrations-with-entity-framework/ 系列目 ...

  6. EF中扩展出Between操作符 (修订版)

    随手记录一下,这是针对原文错误的修改. 原文:EF中扩展出Between操作符 直接使用是错误的,修改后的扩展方法: /// <summary> /// 扩展 Between 操作符 // ...

  7. 如何在EF中实现left join(左联接)查询

    在EF中,当在dbset使用join关联多表查询时,连接查询的表如果没有建立相应的外键关系时,EF生成的SQL语句是inner join(内联),对于inner join,有所了解的同学都知道,很多时 ...

  8. EF中执行sql语句,以及事务

    EF to sql string sql = "select T_Task.BSID,T_Task.CloseDate,T_Task.CompleteDate,T_Task.CloseUse ...

  9. EF架构~在ef中支持IQueryable级别的Contains被翻译成了Exists,性能可以接受!

    回到目录 Entityframeworks很聪明 不错,非常不错!ef里的contains比linq to sql里的contains有了明显的提升,事实上,是在进行SQL语句翻译上有所提升,在lin ...

随机推荐

  1. Android的ImageView介绍-android学习之旅(二十二)

    ImageView简介 imageView继承于View,主要用于显示图片,凡是Drawable对象都可以用它显示. ImageView直接派生了ImageButton和ZoomButton等组件. ...

  2. UNIX环境高级编程——网络编程常用函数及结构

    IP地址的转换 #include <arpa/inet.h>  int inet_aton(const char *strptr,                     struct i ...

  3. python类:属性

    http://blog.csdn.net/pipisorry/article/details/50708616 Python 中的 property 属性 Python中有个很赞的概念,叫做prope ...

  4. 用过的一些Android设备调试特性注意点(挖坑帖)

    华为3C Activity切换动画偏快. 显示大图时不容易出现OOM(应用最大内容要比其他手机大一点),所以调试OOM问题时不要用此手机,否则难以发现问题. 小米3 不要调用系统的裁图功能.因为返回的 ...

  5. 【FPGA学习】Verilog之加法器

    在fpga工程应用设计中,随处可见加法器,乘法器等等.现在将一些常用模块和心得体会先记录下来,以便日后使用. 一位半加器: module halfadder(cout,sum,a,b); output ...

  6. SQL Server扫盲系列——安全性专题——SQL Server 2012 Security Cookbook

    由于工作需要,最近研究这本书:<Microsoft SQL Server 2012 Security Cookbook>,为了总结及分享给有需要的人,所以把译文公布.预计每周最少3篇.如有 ...

  7. 利用编辑距离(Edit Distance)计算两个字符串的相似度

    利用编辑距离(Edit Distance)计算两个字符串的相似度 编辑距离(Edit Distance),又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数.许可 ...

  8. python安装json的方法;以及三种json库的区别

    python中的json解释库有好几个,不同版本使用方法不同. 常用有 json-py 与smiplejson 两个包 其中,json-py 包含json.py外,还有一个minjson,两者用法上有 ...

  9. 主线程中也不绝对安全的 UI 操作

    从最初开始学习 iOS 的时候,我们就被告知 UI 操作一定要放在主线程进行.这是因为 UIKit 的方法不是线程安全的,保证线程安全需要极大的开销.那么问题来了,在主线程中进行 UI 操作一定是安全 ...

  10. HTML5 移动开发入门知识点

    转自:http://www.cnblogs.com/blog-zwei1989/archive/2012/12/12/2815049.html 1.先来看淘宝无线wiki要求在页面中添加的meta标签 ...