我正在尝试使用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
我的更新实体是否有外键和相应的导航属性,在这种情况下通过反射手动更新它,但我不确定我实际拥有哪些数据检查。
有没有办法让外键和导航属性保持同步添加的实体?或者你有什么建议我会尝试吗?
非常感谢你。
答案 0 :(得分:0)
以下是我最终的结果:
我保留了所有添加实体的单独列表。然后,当我必须恢复由外键支持的导航属性时,我搜索该列表并手动设置导航属性。最难的部分是找出如何检查数据模型是否完全需要这个修复,并找到相应属性的名称。
整个系统仍然存在一些缺陷,以实现最大的通用性,但它可以很好地满足我们的需求。