通过实体框架中的更改跟踪撤消/重做

时间:2014-02-25 17:48:02

标签: c# entity-framework-4 metadata

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

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

澄清:说我有这些课程:

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基本上是过滤器之间的多对多关系,但它实际上包含更多字段,这就是我无法摆脱它的原因。另外,我希望尽可能通用,而不是依赖于我们的实际数据模型。

如果我添加新过滤器然后将其连接到现有过滤器(也可能是新过滤器),则会出现问题。撤消连接仍然可以,但是当我尝试重做我的程序时会崩溃。我可以在恢复的连接中看到外键SinkFilterID具有正确的值,但Sinknull(源可能会发生同样的情况,具体取决于连接的方向)。手动呼叫DetectChanges没有任何区别。在两个现有过滤器之间添加连接(即它们之前已经存储在数据库中)是没有问题的。

此类型的新连接检测到的更改仅包含ChangeTracker的实体更改,并且ObjectStateManger没有任何关系更改。我想这是因为关系已经由外键处理,外键包含在PreviousValues的属性中。

我已经读过EntityState.Added状态的实体获得临时密钥,并且不完全支持对它们进行更改跟踪。我可以以某种方式让这个工作吗?

我试图检查MetadataWorkspace我的更新实体是否有外键和相应的导航属性,在这种情况下通过反射手动更新它,但我不确定我实际拥有哪些数据检查。

有没有办法让外键和导航属性保持同步添加的实体?或者你有什么建议我会尝试吗?

非常感谢你。

1 个答案:

答案 0 :(得分:0)

以下是我最终的结果:

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

整个系统仍然存在一些缺陷,以实现最大的通用性,但它可以很好地满足我们的需求。