在previous question中,有人说:
我遇到了该问题中描述的相同问题:EntityManager.rejectChanges()不会将未映射的属性还原为原始值,而EntityAspect.rejectChanges()会这样做。
在对该问题的回答中,有人提出这可能是由于编码错误造成的。我做了一个plunker来证明这个问题。我的代码中是否存在导致此错误的错误?
编辑 - 更新测试用例:
test("reject changes reverts an unmapped property - only unmapped property changed", 1, function () {
var store = cloneModuleMetadataStore();
var originalTime = new Date(2013, 0, 1);
var Customer = function () {
this.lastTouched = originalTime;
};
store.registerEntityTypeCtor("Customer", Customer);
var manager = newEm(store);
// create a fake customer
var cust = manager.createEntity("Customer", { CompanyName: "Acme" },
EntityState.Unchanged);
var touched = cust.lastTouched();
// we change only the unmapped property (uncomment the next line and the test will pass)
//cust.CompanyName("Beta");
cust.lastTouched(new Date(touched.getTime() + 60000));
//cust.entityAspect.rejectChanges(); // roll back name change
manager.rejectChanges(); // would have same effect. Obviously less granular
ok(originalTime === cust.lastTouched(),
"'lastTouched' unmapped property should be rolled back. Started as {0}; now is {1}"
.format(originalTime, cust.lastTouched()));
});
您可以看到,在此环境中,测试通过entityAspect.rejectChanges()传递,但是使用manager.rejectChanges()失败。如果映射的属性与未映射的属性一起更改,则测试通过。
答案 0 :(得分:1)
好的,你发现的实际上是设计的。 并且......感谢上面的测试,(这使得理解问题变得更加容易)。
此处的问题是对未映射属性的更改不会更改实体的EntityState。做出这个决定是因为这些更改实际上并不需要持久保存到服务器(因为无处可放)。
第二个问题是,当调用EntityManager.rejectChanges时,我们只处理具有Added,Modified或Deleted EntityState的实体。由于仅对未映射的属性进行ONLY更改的实体不属于此类别,因此永远不会进行实体级别rejectChanges调用。
有几种解决方法。
请随意提出一个对您有意义的替代方案。我们已考虑添加设置以允许您配置未映射属性的处理。 (其中包括未映射的属性更改是否会更改实体状态)。
我不能重复这个......并且查看代码,EntityManager.rejectChanges只是调用了经理中所有实体的EntityAspect.rejectChanges。
所以有几种可能性
1)您没有看到rejectChanges正常工作的EntityAspect实际上并未“附加”到EntityManager。
2)在两种情况下,您实际上并没有比较SAME实体上“rejectChanges”的行为。
查看Breeze zip中DocCode示例中的测试用例。这些测试不需要UI,通常很短。如果你可以粘贴一个在那个环境中失败的简单测试,我会看看。涉及到UI通常会使图片变得模糊。