在实体框架中使用变更跟踪撤消/重做 [英] Undo / Redo with change tracking in Entity Framework

查看:183
本文介绍了在实体框架中使用变更跟踪撤消/重做的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用POCO实体实现基于实体框架的撤消/重做功能。因此,在每次更改之后,我想跟踪我调用ChangeTracker进行任何对实体的修改,我将调用 ObjectStateManger 来更改关系(即导航属性)。我存储所有的变化与当前和以前的值,以便能够在历史中来回。

I'm trying to implement an Undo / Redo feature based on entity framework with POCO entities. Therefor after each change that I want to track I call the ChangeTracker for any modification to entities an I call the ObjectStateManger for changes to relationships (i.e. navigation properties). I store all the changes with the current and previous values to be able to go back and forth in the history.

我的问题是,对于具有导航属性和对应的外键,如果引用的实体新添加到DbContext中,则这两个值未正确同步。

My problem now is that for entities with a navigation property and a corresponding foreign key these two values are not properly synced if the referenced entity was newly added to the DbContext.

澄清:说我有这些课程:

To clarify: Say I have these classes:

public class EntityFilter
{
    [Key]
    public Guid ID { get; set; }

    public virtual ICollection<EntityConnection> IsSource { get; set; }

    public virtual ICollection<EntityConnection> IsSink { get; set; }

    //other stuff
}

public class EntityConnection
{
    [Key]
    public Guid SinkFilterID { get; set; }

    [ForeignKey("SinkFilterID")]
    public virtual EntityFilter Sink { get; set; }

    public Guid SourceFilterID { get; set; }

    [ForeignKey("SourceFilterID")]
    public virtual EntityFilter Source { get; set; }

    //more stuff
}

EntityConnection 基本上是过滤器之间的多对多关系,但它实际上包含更多的字段,这就是为什么我无法摆脱它。此外,我想要尽可能的一般,而不依赖于我们的实际数据模型。

EntityConnection is basically a many-to-many relationship between filters, but it actually contains more fields which is why I cannot get rid of it. Also I want to be as general as possible and not depend on our actual data model.

如果我添加一个新的过滤器,然后将其连接到现有的过滤器,则会出现问题(也可能是一个新的)。撤销连接仍然可以,但是当我尝试重做我的程序将崩溃。在恢复的连接中可以看到外键 SinkFilterID 具有正确的值,但 Sink null (根据连接的方向,源可能会发生这种情况)。手动调用 DetectChanges 没有区别。在两个现有过滤器之间添加连接(即它们已经存储在db中)没有任何问题。

The problem arises if I add a new filter and then connect it to an existing filter (could also be a new one). Undoing the connection is still ok, but when I try to redo my program will crash. I can see in the restored connection that the foreign key SinkFilterID has the correct value but Sink is null (the same might happen for source, depending on the direction of the connection). Manually calling DetectChanges makes no difference. Adding a connection between two existing filters (i.e. they are already stored in the db before) is no problem.

此类型的新连接检测到的更改只包含实体从 ChangeTracker 中更改,并且与 ObjectStateManger 之间没有关系更改。我猜这是因为这个关系已经由外键处理了,这个外键包含在 PreviousValues 的属性中。

The detected changes for a new connection of this type only contain entity changes from the ChangeTracker and no relationship changes from the ObjectStateManger. I guess this is because the relationship is already handled by the foreign key, which is included in the properties from PreviousValues.

我已经看到 EntityState.Added 状态中的实体获取临时密钥,并且不完全支持对它们进行更改跟踪。我可以得到这样的工作吗?

I've read that entities in the EntityState.Added state get temporary keys and that change tracking for them is not fully supported. Can I get this to work somehow?

如果我更新的实体已经有了,我试图检查$ code MetadataWorkspace 外键和相应的导航属性,在这种情况下通过反射手动更新,但我不知道我实际需要检查什么数据。

I've tried to check with the MetadataWorkspace if my updated entities have a foreign key and a corresponding navigation property and in that case update it manually via reflection, but I'm not sure what data I actually have to check.

是否有保持外键和导航属性同步添加实体的方法?或者你有什么建议可以尝试吗?

Is there a way to keep foreign keys and navigation properties to added entities in sync? Or do you have any suggestions what I might try?

非常感谢你。

推荐答案

这是我最后的结论:

所有添加实体的单独列表。然后,当我需要恢复由外键支持的导航属性时,我搜索该列表并手动设置导航属性。最困难的部分是找出如何检查数据模型,如果这个修复是所有需要的,并找到相应的属性的名称。

I keep a separate list of all the added entities. Then when I have to restore a navigation property that is backed by a foreign key I search that list and manually set the navigation property. The hardest part was to figure out how to check in the data model if this fixup was at all needed and to find the name of the corresponding property.

整个系统仍然对于最大的普遍性有一些缺陷,但它对我们所需要的效果非常好。

The overall system still has some flaws for maximum generality but it works quite well for what we need.

这篇关于在实体框架中使用变更跟踪撤消/重做的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆