這節介紹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系列教程彙總