zoukankan      html  css  js  c++  java
  • Entity Framework入门教程(19)---EF中使用事务

    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系列教程汇总

  • 相关阅读:
    LinkedList的使用方法
    规范HTML页面
    HTML总结(一)
    HTML标签学习总结
    java---线程池的使用
    java对excel表格的操作
    java对cookie及Session的操作
    硬盘分区工具gparted使用
    镜像, 转置, 锐化, 灰度,旋转
    ffmpeg解码
  • 原文地址:https://www.cnblogs.com/wyy1234/p/9645796.html
Copyright © 2011-2022 走看看