【问题标题】:Rollback additions / removals to DBSets of the DbContext using a transaction in Entity Framework使用实体框架中的事务回滚对 DbContext 的 DBSet 的添加/删除
【发布时间】:2018-09-12 05:30:19
【问题描述】:

我在使用 Entity Framework 6 的项目中的一般模式是

  1. 为添加创建新实体
  2. 将实体添加到DbContext 的相关DBSet
  3. 设置这些对象的属性
  4. 致电DbContext.SaveChanges()

下面是我的意思的一些伪代码:

    // Psuedo code to illustrate process. 
    void AddProcess()
    {

        var modelsToAdd = GetModelsToAdd();

        try
        {
            _context.Models.AddRange(modelsToAdd);

            _context.SaveChanges();

            // If we get here all is good.
        }
        catch (Exception ex)
        {
            _context.RemoveRange(modelsToAdd);
            throw;
        }
        finally
        {
            //....
        }
    }

我知道SaveChanges() 方法在内部创建了自己的Transaction,因此如果在保存过程中出现异常,它将被回滚。但是,如果在SaveChanges() 期间发生错误,我想要从DbSet 中删除(2)中添加的实体。基本上,就好像“添加”过程从未发生过一样。

如您所见,目前我正在缓存涉及的模型列表,然后在发生异常时将其删除。

我想知道有没有更好的方法让事务自动为我完成这项工作?那么,SaveChanges() 的内部Transaction 回滚是否也可以回滚对DbSet 的任何添加?或者可以使用其他交易吗?

实现我所寻找的最佳/首选方式是什么?我对 EF 还很陌生,所以这可能很明显。

【问题讨论】:

    标签: c# entity-framework entity-framework-6 dbcontext


    【解决方案1】:

    https://code.msdn.microsoft.com/How-to-undo-the-changes-in-00aed3c4 中的选项 #1 通常足以满足您希望在不删除和重新实例化上下文的情况下回滚 DbContext 中的更改的大多数实现。通常,请求会失败并且调用会结束,因此 DbContext 范围应该结束,直到在新请求中尝试重试。

    如果有一个非常好的理由立即重试/替代操作,我只会考虑回滚 DbContext。在 SaveChanges 失败的情况下想要回滚 DbSet 通常表明 DbContext 保持活动的时间过长。

    在失败的情况下需要保存的重要内容(如日志记录)应使用专用的 DbContext,以便它们的更新不会受到应用程序 DbContext 上的失败 SaveChanges 的阻碍。

    【讨论】:

    • 嗨史蒂夫,很抱歉回复晚了。谢谢你的帮助。我采用了您提供的链接中包含的方法。
    猜你喜欢
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    • 2014-11-13
    • 1970-01-01
    相关资源
    最近更新 更多