EF中使用事务

这节介绍EF6中事务的使用。EF core中事务的使用方式和EF6中一模一样。

1.EF中的默认的事务

  默认情况下,当我们执行一个SaveChanges()方法时就会新建了一个事务,然后将context中的CUD操作都在这个事务中进行。Context中有多个SaveChanges()时,每一个SaveChanges()都会执行一个单独的事务。一个栗子:

using (var context = new SchoolContext())
{
context.Database.Log = Console.Write; var standard = context.Standards.Add(new Standard() { StandardName = "1st Grade" }); context.Students.Add(new Student()
{
FirstName = "Rama",
StandardId = standard.StandardId
}); context.SaveChanges(); context.Courses.Add(new Course() { CourseName = "Computer Science" });
context.SaveChanges();
}

上边的代码执行结果如下:

从上边的栗子我们可以清楚地看到每个SaveChanges()方法都开启了一个事务。这时有一个问题:有没有什么办法让多个SaveChanges()在一个事务中执行呢?这样的话就可以减少事务创建、开启进而提升性能了。

2.一个事务执行多个SaveChanges()方法

EF6和EF core中提供了两种方法实现在一个事务中执行多个SaveChanges()方法。

DbContext.Database.BeginTrasaction():新建一个事务,在新建的事务内进行context.SaveChanges()

DbContext.Database.UseTransaction(trans):使用一个context作用域外的现有的事务,多个context都可以在通过这个事务一起提交。

1.DbContext.Database.BeginTrasaction()

一个栗子:

using (var context = new SchoolContext())
{
context.Database.Log = Console.Write; using (DbContextTransaction transaction = context.Database.BeginTransaction())
{
try
{
var standard = context.Standards.Add(new Standard() { StandardName = "1st Grade" }); context.Students.Add(new Student()
{
FirstName = "Rama",
StandardId = standard.StandardId
});
context.SaveChanges();
// 第一个SaveChanges()方法后抛出异常
throw new Exception(); context.Courses.Add(new Course() { CourseName = "Computer Science" });
context.SaveChanges(); transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
Console.WriteLine("Error occurred.");
}
}
}

执行结果:

我们可以看到所有的SaveChanges()都被回滚了。如果把抛出异常的代码注释掉那么执行效果如下:

2.DbContext.Database.UseTransaction(trans)

使用DbContext.Database.UseTransaction(trans),我们通过参数传入的是一个作用域外的事务,注意:这里EF不会再新建内置的事务,而是使用通过参数传入的事务。

一个栗子:

private static void Main(string[] args)
{
string providerName = "System.Data.SqlClient";
string serverName = ".";
string databaseName = "SchoolDB"; // 目标数据库
SqlConnectionStringBuilder sqlBuilder =new SqlConnectionStringBuilder();
sqlBuilder.DataSource = serverName;
sqlBuilder.InitialCatalog = databaseName;
sqlBuilder.IntegratedSecurity = true; using (SqlConnection con = new SqlConnection(sqlBuilder.ToString()))
{
con.Open();
     //在DbContext作用域外新建一个事务
using (SqlTransaction transaction = con.BeginTransaction())
{
try
{
         //使用上边的创建的事务
using (SchoolContext context = new SchoolContext(con, false))
{
context.Database.UseTransaction(transaction); context.Students.Add(new Student() { Name = "Ravi" });
context.SaveChanges();
} using (SchoolContext context = new SchoolContext(con, false))
{
context.Database.UseTransaction(transaction); context.Grades.Add(new Standard() { GradeName = "Grade 1", Section = "A" });
context.SaveChanges();
}
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback(); Console.WriteLine(ex.InnerException);
}
}
}
}

EF系列目录链接:Entity Franmework系列教程汇总

Entity Framework入门教程(19)---EF中使用事务的更多相关文章

  1. Entity Framework入门教程(3)---EF中的上下文简介

    1.DbContext(上下文类) 在DbFirst模式中,我们添加一个EDM(Entity Data Model)后会自动生成一个.edmx文件,这个文件中包含一个继承DbContext类的上下文实 ...

  2. Entity Framework入门教程(4)---EF中的实体关系

    这一节将总结EF是怎么管理实体之间的关系.EF与数据库一样支持三种关系类型:①一对一 ,②一对多,③多对多. 下边是一个SchoolDB数据库的实体数据模型,图中包含所有的实体和各个实体间的关系.通过 ...

  3. Entity Framework入门教程(5)---EF中的持久化场景

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

  4. Entity Framework入门教程(13)---EF中的高并发

    EF中的高并发 这里只介绍EF6中database-first开发方案的高并发解决方案,code-first开发方案中的高并发会在以后的EF CodeFirst系列中介绍. EF默认支持乐观并发:我们 ...

  5. Entity Framework入门教程(7)--- EF中的查询方法

    这里主要介绍两种查询方法 Linq to entity(L2E)和Sql 1.L2E查询 L2E查询时可以使用linq query语法,或者lambda表达式,默认返回的类型是IQueryable,( ...

  6. Entity Framework入门教程(2)---EF工作流程

    EF工作流程 1.EF基本CRUD流程 下边的图就可以很清晰地展示EF的CRUD操作的基本工作流程: 这里做一个EF CRUD操作的简单总结:1.定义模型:这是EF工作的前提,定义模型包括定义领域类( ...

  7. Entity Framework入门教程(6)--- 在线场景中保存数据

    在线场景中保存数据 在线场景中保存实体数据是一项相当容易的任务,因为使用的是同一个context,这个context会自动跟踪所有实体发生的更改. 下图说明了在线场景中的CUD(创建,更新,删除)操作 ...

  8. Entity Framework入门教程(11)---EF6中的异步查询和异步保存

    EF6中的异步查询和异步保存 在.NET4.5中介绍了异步操作,异步操作在EF中也很有用,在EF6中我们可以使用DbContext的实例进行异步查询和异步保存. 1.异步查询 下边是一个通过L2E语法 ...

  9. Entity Framework入门教程(12)--- EF进行批量添加/删除

    EF6添加了批量添加/删除实体集合的方法,我们可以使用DbSet.AddRange()方法将实体集合添加到上下文,同时实体集合中的每一个实体的状态都标记为Added,在执行SaveChange()方法 ...

随机推荐

  1. python 3.7 安装mysqlclient 错误解决

    安装时出现的问题 >pip3.7 install mysqlclientCollecting mysqlclient  Using cached https://files.pythonhost ...

  2. LeetCode算法题-Baseball Game(Java实现)

    这是悦乐书的第288次更新,第305篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第156题(顺位题号是682).你现在是棒球比赛点记录器.给定一个字符串列表,每个字符串 ...

  3. 3星|《给产品经理讲技术》:APP开发技术介绍,没有技术背景的话恐怕只能看懂书中的比喻和结论

    基本是APP开发涉及到的相关技术的入门级介绍.涉及到的知识点与技术细节比较多,不少技术相关的内容并没有像标题暗示的那样没有技术背景也可以看懂,而是涉及到许多专业的术语.原理.也有一些内容是用比喻的方法 ...

  4. JDBC获得连接时报connection refused

    1,检查数据库服务器的IP是否正确. 2,检查用户名密码是否正确. 3,检查SID,获selecte instance_name from v$instance;

  5. Redis操作string

    Redis简介: ''' redis: 缓存,例如两个个程序A,B之间要进行数据共享,A可以把数据存在redis(内存里),其他程序都可以访问redis里的数据, 这样通过中间商redis就实现了两个 ...

  6. Python开发【第二篇】运算符

    "+" 加号 __author__ = 'Tang' a = 8 b = 9 c = a + b a = 8.0 b = 9 c = a + b print(c) # 17.0 a ...

  7. slice()和splice()区别

    1.slice(start,end):方法可从已有数组中返回选定的元素,返回一个新数组,包含从start到end(不包含该元素)的数组元素. 注意:该方法不会改变原数组,而是返回一个子数组,如果想删除 ...

  8. 数据规范化——sklearn.preprocessing

    sklearn实现---归类为5大类 sklearn.preprocessing.scale()(最常用,易受异常值影响) sklearn.preprocessing.StandardScaler() ...

  9. web服务器、tomcat、servlet是什么?它们之间的关系又是什么?

    今天偶然看到常见web服务器的介绍有Apache HTTP server.Nginx.Microsoft IIS.GWS,心中不禁产生了疑问,这些都是什么呢?一直认为tomcat就是web服务器,以下 ...

  10. python小白——进阶之路——day3天-———容器类型数据+Number类型强制类型转换

    -->Number 部分 int :     整型   浮点型 布尔类型  纯数字字符串 float:    整型   浮点型 布尔类型  纯数字字符串 complex:  整型   浮点型 布 ...