我在EntityManager中创建了一个新实体,如下所示:
var newCust = manager.createEntity('Customer', { Name: 'MyNewCustomer' });
它的Id是正确生成的。在按钮上单击我在服务器上保存实体:
manager.saveChanges([newCust]).then(function (saveResult) {
alert('saved!');
}
现在一切都很完美但是,newCust中的实体保持它的EntityState“已添加”。它不会更改为“未更改”。
我调试了一点,发现了,在breeze的函数“mergeEntity(mc,node,meta)”中,下面的代码发生了 - 没有找到实体(尽管它搜索的密钥是相同的Id - Id-Fixup工作正常):
var targetEntity = em.findEntityByKey(entityKey);
因此,每次保存新实体时,都会在我的EntityManager中创建一个新实体。当我重新加载页面时,实体被正确标记并正常工作。唯一的问题是,每次保存更改时都会保存一个新实体。
感谢您的帮助!
修改1:
我发现了问题,我不确定Breeze对我的期望是什么。当我的ContextProvider保存实体时,它会发送一个DB-Update-Command(对于所有属性),然后返回。问题是,saveResult-Object的Id仍然是“tempId”而不是真实的 - 所以当客户端的Breeze收到对象时,它不再在entityManager中找到它,因为Key-Fixup发生了已经
Breeze期望从saveResult获得什么?此时对象在数据库中的表示形式? - 会有意义,但我没有找到它。
编辑2:
看起来我无法替换saveWorkState.saveMap中的对象(EntityInfo info.Entity是readonly)。我想要做的是创建新添加的对象并返回此对象而不是微风发送给我的对象。我已经计算了新创建的对象和新的“真实”Id的值。 NoDB-Sample似乎只是覆盖了newId的Id,但其他任何属性都没有改变。也许我没有正确使用这种机制?
答案 0 :(得分:0)
为了确保在我的SaveResult中返回的所有EntityInfos都是数据库的最新表示,我只需清除saveWorkState.SaveMap-Lists
saveWorkState.SaveMap[n].Clear()
并添加新的表示
saveWorkState.SaveMap[n].AddRange(newEntityInfos);
并为每个添加或修改的实体创建一个新的EntityInfo,其中包含数据库返回的对象
private EntityInfo SaveEntity(List<KeyMapping> keyMap, EntityInfo info) {
EntityInfo result = info;
switch (info.EntityState) {
case EntityState.Added: {
// CreateInDatabase
// Possible changes in object properties happen (for calculated values)
...
var newObj = GetObjectAgainFromDatabase(info.Entity);
keyMap.Add(new KeyMapping() { EntityTypeName = bu.RuntimeClass.FullName, TempValue = (MyObject)info.Entity.Id, RealValue = newObj.Id });
result = CreateEntityInfo(newObj, EntityState.Added);
break;
}
case EntityState.Deleted: {
// Delete in Database
// EntityInfo doesn't have to change
break;
}
case EntityState.Modified: {
// Update in Database
result = CreateEntityInfo(bu.WrappedPOCO, EntityState.Modified);
break;
}
default: //EntityState.Detached, EntityState.Unchanged
break;
}
return result;
}
欢迎对此解决方案发表任何评论!