Breeze调用importEntities时导航属性未维护的撤销功能问题咨询
使用Breeze JS EntityManager的export/import实现撤销时的导航属性维护问题
我最近在用Breeze的JavaScript版EntityManager,打算用exportEntities/importEntities方法实现撤销功能:打开对话框时生成实体快照,取消时调用importEntities并传入快照,用OverwriteChanges合并策略来撤销变更。不过遇到了一个棘手的问题——新增(Added)带存储生成键的实体处理。
导入这类实体时,它们会被分配新的临时键,而且会作为新实例导入,原来的实例还会留在EntityManager中,必须手动移除。起初我以为EntityManager内的导航属性会自动更新指向新实例,但存在例外场景:
- 当
entityA初始状态为Unchanged,关联新增状态的entityB后变为Modified,执行importEntities后,entityB被替换为新实例,但entityA的导航属性仍指向原entityB实例 - 手动移除原实例后,该导航属性会变成无效引用,最终导致
saveChanges时触发数据库外键冲突 - 但如果
entityA为Added状态时,导航属性的维护就完全正常
我尝试在DocCode的C#测试中复现这个问题,但没有成功,推测C#与JavaScript版本的实现存在差异,目前使用的是npm最新版的breeze-client 1.3。想请教两个问题:
- 如何确保所有场景下导航属性都能被正确维护?
- 是否有其他无需手动修复外部引用的撤销实现方案?
附测试代码
[TestMethod] public async Task ImportChangedEntityAndMaintainNavigationPropertyReferencesToIt() { var manager = new EntityManager(_serviceName); await manager.FetchMetadata(); // Metadata must be fetched before CreateEntity() can be called var order = manager.CreateEntity<Order>(new {OrderID = 1}, EntityState.Unchanged); //var order = manager.CreateEntity<Order>(EntityState.Unchanged); var employee = manager.CreateEntity<Employee>(); order.Employee = employee; var exportData = manager.ExportEntities(); var imported = manager.ImportEntities(exportData, new ImportOptions(MergeStrategy.OverwriteChanges)); var importedOrder = imported.ImportedEntities.OfType<Order>().Single(); Assert.AreSame(order, importedOrder); var managerOrder = manager.GetEntities<Order>().Single(); Assert.AreSame(order, managerOrder); Assert.AreEqual(importedOrder.Employee.EntityAspect.EntityState, EntityState.Added); Assert.AreNotSame(importedOrder.Employee, employee); //Entities with temporary keys are replaced with new instances. Assert.IsFalse(importedOrder.Employee.EntityAspect.EntityKey.Equals(employee.EntityAspect.EntityKey)); //Entities with temporary keys are assigned new ones. }
内容的提问来源于stack exchange,提问作者Scott Munro
相关产品推荐
相关产品推荐

