【问题标题】:Rollback in Entity Framework 4.0Entity Framework 4.0 中的回滚
【发布时间】:2010-07-12 10:07:08
【问题描述】:

我有一个 Customer 类,其中包含一个 Contact 类,该类存储该特定客户的所有联系人,因此它们与外键关系链接。

这是我的场景:用户编辑包括联系人在内的客户信息,然后决定点击“取消”按钮。联系人绑定到网格,因此每次进行编辑/添加/删除时,它都会自动更新缓存数据库上下文中的联系人实体。那么如何回滚用户对联系人实体所做的所有更改呢?

我尝试了以下方法(在谷歌搜索答案后):

    public static void CustomerRollback(Customer customer)
    {
        dbContext.Refresh(System.Data.Objects.RefreshMode.StoreWins, customer);
        dbContext.Refresh(System.Data.Objects.RefreshMode.StoreWins, customer.Contacts);
    }

但这没有用。还有其他想法吗?请注意,我的问题仅在于回滚联系人实体。我猜首先导致问题的原因是网格会自动更新缓存的实体。因此,当我尝试取消时,每个联系人的 EntityState 已经更改为修改状态(EntityState.Added、EntityState.Deleted 等)。我是否需要遍历联系人并检查他们的 EntityState 属性并对其进行处理?

谢谢 凯撒

【问题讨论】:

  • 上下文旨在成为一个工作单元。 “回滚”工作的方法是处置上下文。听起来您将上下文保留的时间过长。这会产生深远的负面影响。
  • 你和 Devart 下面都建议处理上下文,但这是否意味着我必须重新从数据库中获取所有数据?那会阻碍性能。顺便说一句,上下文太长不是问题,因为这个问题在我启动应用程序的早期就出现了。我是唯一一个测试它的用户,所以也没有并发问题。
  • 您过早地进行了优化。如果您使用单例上下文,您的长期性能可能已经很差了。不要因为想象中的性能影响而拒绝正确的做法,而是按照预期的方式使用上下文,然后通过分析和点修复来解决任何性能问题。
  • 谢谢克雷格,我真的很感谢一个好的可靠教程的链接。我似乎无法在外面找到好的。我来自 NHibernate 背景,我刚刚开始了解 EF 4.0。这在理论上似乎很容易,但怪癖和未记录的问题是一个主要的挫折。任何帮助将不胜感激。谢谢
  • 在 EF 中使用 ObjectContext 就像在 NH 中使用 Session 一样。这几乎是相同的想法。在这两种情况下,它们都是一个工作单元。

标签: entity-framework-4 foreign-key-relationship


【解决方案1】:

这就是我所做的,这是 Entity Framework 1.0 中的一个变通方法,我希望 EF 4.0 有一个更简单的方法来回滚对象上下文。如果您知道更好的方法,请与我分享,这似乎暂时有效:

        // delete added objects that did not get saved
        foreach (var entry in dbContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added))
        {
            if (entry.Entity != null)
                dbContext.DeleteObject(entry.Entity);
        }
        // Refetch modified objects from database
        foreach (var entry in dbContext.ObjectStateManager.GetObjectStateEntries(EntityState.Modified))
        {
            if (entry.Entity != null)
                dbContext.Refresh(System.Data.Objects.RefreshMode.StoreWins, entry.Entity);
        }
        // Recover modified objects that got deleted
        foreach (var entry in dbContext.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted))
        {
            if (entry.Entity != null)
                dbContext.Refresh(System.Data.Objects.RefreshMode.StoreWins, entry.Entity);
        }

        dbContext.AcceptAllChanges();

【讨论】:

    【解决方案2】:

    看看AcceptAllChanges 方法。 SaveChanges(SaveOptions) 也很有帮助。
    另一种解决方案是将 ObjectContext 实例用作工作单元并为操作创建它,并且仅在必要时(当用户确认有必要时)保存更​​改,只是在另一种情况下处理上下文 - 这将丢弃更改根据上下文制作。

    【讨论】:

    • 但是如果我处理上下文,那么我将不得不为应用程序的其余部分重新获取所有数据......那会很糟糕。我会用谷歌搜索你对工作单元的建议。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 2015-10-26
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多