EF中关于TransactionScope的使用
前提条件
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的使用的更多相关文章
- EF 中事务的书写
在EF 中怎么使用事务? 这个问题纠结了我好久,直到有人跟我一起讨论,我和同事一起讨论查资料. 查的好多资料都是使用 using (TransactionScope scope = new Trans ...
- EF中的transaction的使用范例
注意一点: 在EF中使用事物后,对于一个新增的model,在saveChanges后,可以得到该实体的自增ID,但在提交事物之前, 该数据并没有真正的新增到DB中,但此时可以得到model新增的自增I ...
- 在EF中正确的使用事务
1.EF中使用事务: using (TransactionScope tran = new TransactionScope()) { try { using(var _context = new D ...
- 1.【使用EF Code-First方式和Fluent API来探讨EF中的关系】
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/relationship-in-entity-framework-using-code-firs ...
- 2.EF中 Code-First 方式的数据库迁移
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/code-first-migrations-with-entity-framework/ 系列目 ...
- EF中扩展出Between操作符 (修订版)
随手记录一下,这是针对原文错误的修改. 原文:EF中扩展出Between操作符 直接使用是错误的,修改后的扩展方法: /// <summary> /// 扩展 Between 操作符 // ...
- 如何在EF中实现left join(左联接)查询
在EF中,当在dbset使用join关联多表查询时,连接查询的表如果没有建立相应的外键关系时,EF生成的SQL语句是inner join(内联),对于inner join,有所了解的同学都知道,很多时 ...
- EF中执行sql语句,以及事务
EF to sql string sql = "select T_Task.BSID,T_Task.CloseDate,T_Task.CompleteDate,T_Task.CloseUse ...
- EF架构~在ef中支持IQueryable级别的Contains被翻译成了Exists,性能可以接受!
回到目录 Entityframeworks很聪明 不错,非常不错!ef里的contains比linq to sql里的contains有了明显的提升,事实上,是在进行SQL语句翻译上有所提升,在lin ...
随机推荐
- Android版本更新时对SQLite数据库升级或者降级遇到的问题
SQLite是Android内置的一个很小的关系型数据库.SQLiteOpenHelper是一个用来辅助管理数据库创建和版本升级问题的抽象类.我们可以继承这个抽象类,实现它的一些方法来对数据库进行自定 ...
- www-authenticate与BASE-64认证技术
www-authenticate是一种简单的用户身份认证技术.很多验证都采用这种验证方式,尤其在嵌入式领域中.优点:方便缺点:这种认证方式在传输过程中采用的用户名密码加密方式为BASE-64,其解码过 ...
- 网站开发进阶(三十七)JSP页面跳转问题解决
JSP页面跳转问题解决 PS:本篇博文质量欠佳,仅供个人学习之用. 前言 在做Web开发时,对别人的应用(jsp+servlet)进行服务器部署时出现了页面跳转无效的情况.但是项目在本地未出现此状况. ...
- Leetcode_28_Implement strStr
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41452047 Implement strStr(). Re ...
- C 语言之银行ATM机界面
其实就是简单地对switch的用法,希望能给广大读者一些思路,写出自己的创意界面. #include <stdio.h> void main() { char SelectKey,Cred ...
- 第一篇、vlc-android之开篇介绍
转载请注明出处:http://blog.csdn.net/cuiran/article/details/30054835 最近一直研究android的视频直播部分,从最开始的直接播放本地视频文件,到使 ...
- Spring揭秘读书笔记 八 数据访问异常体系
这篇博客 来自spring揭秘一书的第十三章 为什么要有访问异常都有一个体系,这个我们得从DAO模式说起. DAO模式 任何一个系统,不管是一个最简单的小系统,还是大规模的系统,都得跟数据打交道,说白 ...
- Mahout系列之-----相似度
Mahout推荐系统中有许多相似度实现,这些组件实现了计算不能User之间或Item之间的相似度.对于数据量以及数据类型不同的数据源,需要不同的相似度计算方法来提高推荐性能,在mahout提供了大量用 ...
- 【Qt编程】基于Qt的词典开发系列<一>--词典框架设计及成品展示
去年暑假的时候,作为学习Qt的实战,我写了一个名为<我爱查词典>的词典软件.后来由于导师项目及上课等原因,时间不足,所以该软件的部分功能欠缺,性能有待改善.这学期重新拿出来看时,又有很多东 ...
- 怎样写一个与Win8 IE11兼容的标准BHO?
怎样写一个与Win8 IE11兼容的标准BHO? 环境:Windows8.1 x86 IE11(其它环境未讨论) 作者:magictong 日期:2014/02/02 概述 微软在2013年6月份推出 ...