【问题标题】:Understanding Transactions in Entity Framework了解实体框架中的事务
【发布时间】:2011-11-26 00:19:19
【问题描述】:

您好,我正在尝试将事务与实体框架一起使用。网上有这么多关于实现交易的不同方式的信息,我必须说我对正确的方式有点困惑。我有一个包含两个表 Employee 和 Company 的示例数据库。 Employee 表有一个引用公司 ID 的外键。考虑到我想实现一个事务,在该事务中我将一条记录插入到 Company 表中,然后将一条记录插入到 Employee 表中,我想这样做以便只有在两者都成功时才插入记录,我有以下代码。

public void addCompanyToDatabase()
    {
        using (var context = new myTestEntities())
        {
            context.Connection.Open(); //added this as was getting the underlying   
            //provider failed to open
            using (TransactionScope scope = new TransactionScope())
            {
                try
                {
                    Company c = new Company();
                    c.Name = "xyz";
                    context.Companies.AddObject(c);
                    context.SaveChanges();

                    //int a = 0;
                    //int b = 5 / a;

                    Employee e = new Employee();
                    e.Age = 15;
                    e.Name = "James";
                    e.CompanyId = c.Id;
                    context.Employees.AddObject(e);
                    context.SaveChanges();

                    scope.Complete();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception Occurred");
                }
            }
        }
    }

我想知道这是否是实现交易的正确方式。如果是,那么SaveChanges(false)scope.AcceptAllChanges() 函数的用途是什么。任何信息都会有所帮助。

【问题讨论】:

    标签: c# entity-framework-4 transactions transactionscope


    【解决方案1】:

    在您的情况下,您不需要管理任何连接或事务:Entity Framework 将为您执行此操作。当您不向 EF 提供已打开的连接(但带有连接字符串)时,它将打开一个连接并在调用 context.SaveChanges() 期间启动一个事务。当调用过程中发生故障时,事务将被回滚。

    换句话说,您的方法可以简单地如下所示:

    public void addCompanyToDatabase()
    {
        using (var context = new myTestEntities())
        {
            Company c = new Company();
            c.Name = "xyz";
            context.Companies.AddObject(c);
    
            Employee e = new Employee();
            e.Age = 15;
            e.Name = "James";
            e.CompanyId = c.Id;
            context.Employees.AddObject(e);
    
            // Only call SaveChanges last.
            context.SaveChanges();
        }
    }
    

    【讨论】:

    • 在我的例子中这是有道理的。你能给我一个我需要交易的例子吗?如果我上面提到的代码是实现交易的方法?我想用两种不同的上下文更新记录是一种情况。
    • 我遇到的最常见的需要事务处理的情况是,您需要多次调用SaveChanges。当您需要新对象的(数据库生成的)id,或者当您需要强制 ORM 以特定顺序执行操作时(例如,LINQ to SQL 倾向于在插入后重新排序删除,但这可能会触发数据库约束异常)。
    • 在所有情况下,仍然不需要使用TransactionScope。如果您需要TransactionScope,因为您需要对多个数据库进行原子操作,那么您的系统可能存在设计缺陷。我将TransactionScopes 纯粹用于我的自动化集成测试。只需在 TransactionScope 中调用调用代码,您就可以确保在测试结束时回滚所有(数据库)更改,而无需为此更改任何代码。
    【解决方案2】:

    1-这个服务(我认为事务服务)必须在客户端运行才能支持TransactionScope

    2-当您的应用程序中有两个或更多数据库并且您希望所有数据库更新事务(例如更改上下文的连接字符串)时很有用。

    3-当您有数据库时,最好使用内部实现事务的 SaveChanges()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      相关资源
      最近更新 更多