Entity Framework入門教程(19)---EF中使用事務

EF中使用事務

這節介紹EF6中事務的使用。EF core中事務的使用方式和EF6中如出一轍。html

1.EF中的默認的事務

  默認狀況下,當咱們執行一個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

2.一個事務執行多個SaveChanges()方法

EF6和EF core中提供了兩種方法實如今一個事務中執行多個SaveChanges()方法。post

DbContext.Database.BeginTrasaction():新建一個事務,在新建的事務內進行context.SaveChanges()性能

DbContext.Database.UseTransaction(trans):使用一個context做用域外的現有的事務,多個context均可以在經過這個事務一塊兒提交。ui

1.DbContext.Database.BeginTrasaction()

一個栗子: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

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系列教程彙總

相關文章
相關標籤/搜索