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. Linux PXE无人值守网络装机

    Linux PXE无人值守网络装机 一.实验环境: 2台Linux系统(RHEL6.5版本),1台作为:PXE远程安装服务器(安装dhcp服务.ftp服务.tftp服务),另1台作为:客户端(未装RH ...

  2. debian 9 开机启动

    由于某些软件并没有增加开启启动的服务,很多时候需要手工添加,一般我们都是推荐添加命令到 /etc/rc.local 文件,但是 Debian 9 默认不带 /etc/rc.local 文件,而 rc. ...

  3. 中科曙光I620-G15服务器登录密码破解

    服务器型号:中科曙光I620-G15服务器 系统:windowsserver2008R2 单位:保密 服务器登录密码忘记了,进不去桌面,后来在我们云修网工程师的指导下,顺利绕过密码登录系统,然后修改系 ...

  4. centos7防火墙导致不能访问的

    CentOS 7.0默认使用的是firewall作为防火墙,使用iptables必须重新设置一下 1.直接关闭防火墙 systemctl stop firewalld.service #停止firew ...

  5. python打印电脑串口的信息

    # -*- coding:utf-8 -*- from serial.tools.list_ports import comports port_list = list(comports()) if ...

  6. python开发【lambda篇】

    lambda 与 python 高级函数的配套使用 filter函数 过滤 __author__ = "Tang" # filter(lambda, []) people = [' ...

  7. springboot项目

    https://my.oschina.net/ityouknow/blog/1629066

  8. WiFi其他方法和WiFi事件响

    https://blog.csdn.net/Naisu_kun/article/details/86079455 目的WiFi在使用过程中并非会一直如希望般稳定运行的,为了应对这些情况就需要能够了解W ...

  9. Python学习--Python变量类型

    变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据类型,这些变量可以存储整 ...

  10. 记一次生产数据库"意外"重启的经历

    前言 在一个阳光明媚的下午,电脑右下角传来一片片邮件提醒,同时伴随着微信钉钉的震动,打开一看,应用各种出错,天兔告警,数据库服务器内存爆红,Mysql数据库实例挂掉了. 排查 先交代一下数据库版本: ...