[英]Undo / Redo with change tracking in Entity Framework
我正在尝试基于具有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
具有正确的值,但Sink
为null
(对于源,可能会发生同样的情况,具体取决于连接的方向)。 手动调用DetectChanges
没什么区别。 在两个现有的过滤器之间添加连接(即它们已经存储在数据库中)没有问题。
对于此类型的新连接,检测到的更改仅包含ChangeTracker
实体更改,而ObjectStateManger
没有关系更改。 我猜这是因为该关系已经由外键处理,该外键包含在PreviousValues
的属性中。
我读过EntityState.Added
状态中的实体获取临时键,并且不完全支持对它们的更改跟踪。 我能以某种方式使它工作吗?
我尝试与MetadataWorkspace
进行检查,如果我更新的实体具有外键和相应的导航属性,并且在这种情况下,可以通过反射手动进行更新,但是我不确定实际上必须检查哪些数据。
有没有办法使外键和导航属性与添加的实体保持同步? 还是您有什么建议我可以尝试?
非常感谢你。
我最终得到的是:
我保留了所有添加实体的单独列表。 然后,当我必须还原由外键支持的导航属性时,我会搜索该列表并手动设置导航属性。 最困难的部分是弄清楚如何在数据模型中检入是否完全需要此修补程序,以及如何找到相应属性的名称。
整个系统仍存在一些缺陷,无法实现最大的通用性,但对于我们需要的功能来说效果很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.