这节介绍EF6中事务的使用。EF core中事务的使用方式和EF6中如出一辙。html
默认状况下,当咱们执行一个SaveChanges()方法时就会新建了一个事务,而后将context中的CUD操做都在这个事务中进行。Context中有多个SaveChanges()时,每个SaveChanges()都会执行一个单独的事务。一个栗子:sql
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()在一个事务中执行呢?这样的话就能够减小事务建立、开启进而提高性能了。ide
EF6和EF core中提供了两种方法实如今一个事务中执行多个SaveChanges()方法。post
① DbContext.Database.BeginTrasaction():新建一个事务,在新建的事务内进行context.SaveChanges()性能
②DbContext.Database.UseTransaction(trans):使用一个context做用域外的现有的事务,多个context均可以在经过这个事务一块儿提交。ui
一个栗子:spa
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."); } } }
执行结果:code
咱们能够看到全部的SaveChanges()都被回滚了。若是把抛出异常的代码注释掉那么执行效果以下:server
使用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系列教程汇总