【问题标题】:Added Entitties don't change entityState after entityManager.saveChanges()在 entityManager.saveChanges() 之后添加的实体不会更改 entityState
【发布时间】:2014-05-14 16:14:05
【问题描述】:

我在 EntityManager 中创建一个新实体,如下所示:

var newCust = manager.createEntity('Customer', { Name: 'MyNewCustomer' });

它的 ID 已正确生成。在单击按钮时,我将实体保存在服务器上:

manager.saveChanges([newCust]).then(function (saveResult) {
  alert('saved!');
}

现在一切正常,但是 newCust 中的实体保持其 EntityState“已添加”。它不会更改为“未更改”。

我调试了一下发现,在微风的函数“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 是只读的)。我想做的是创建新添加的对象并返回这个对象,而不是微风发给我的那个。我已经计算了新创建的对象和新的“真实”ID 的值。 NoDB-Sample 似乎所做的只是覆盖了 newId 的 Id,但任何其他属性都没有改变。也许我没有使用这个机制吧?

【问题讨论】:

  • 实体的 ID 类型是什么,你是如何生成的?
  • 这是一个 GUID,它在客户端临时生成,然后在服务器端“真实”生成。所以问题是:在 SaveChangesCore 中,我是否必须将 saveWorkState 中的实体与我从数据库“获取”的对象的新版本交换?所以我必须从数据库中查询每个对象?
  • 实际上,让 Breeze 管理“临时”与“真实”GUID 合并的最简单方法是实现自己的 Breeze KeyGenerator。看看这篇文章是否有帮助。 stackoverflow.com/questions/16699515/…

标签: breeze entitymanager


【解决方案1】:

为了确保在我的 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;
    }

欢迎任何关于此解决方案的 cmets!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多