Breeze EntityManager不删除导入的分离实体?

时间:2015-01-22 20:56:07

标签: breeze

我使用Wards excellent example实现多对多的微风。 (我在他的帖子中脱离了插件,从这里无法链接到它不知道为什么)

一切都运行良好,更改总是正确保存到数据库。

我正在使用2个不同的(BreezeJS)EntityManagers:一个用于编辑,一个用作我的" master"。在将编辑器Em保存到数据库时,它会将所有更改导入到主Em中,以便它们保持同步。这对我的所有其他功能都非常有效。

但是,在保存多对多映射时,由于某种原因,任何已删除的映射都不会从主Em中删除。 (当我添加映射时,它们会立即显示在主Em中)。

我是否需要采取另一个步骤让我的主Em移除导入的分离实体?

(仅供参考,一切都正确保存到服务器,如果我进行硬页面刷新,我的所有实体都会正确显示)。

我在编辑器Em上删除实体的代码:myEntity.entityAspect.setDeleted();

下面的函数将从编辑器Em中导出已更改的实体:

  function exportToMasterAfterSavingSuccess(saveResult){
  if(saveResult.entities)
    masterEm.importEntities(manager.exportEntities(entities, false));
}

master em上的相应导入功能:

function importEntities(entities){
 var imported = manager.importEntities(entities,{ mergeStrategy: breeze.MergeStrategy.OverwriteChanges});
}

3 个答案:

答案 0 :(得分:0)

请使用最新发布的breeze(1.5.3)版试试。那里修复了一个非常类似的错误。

而且要明确,导出永远不能包含' detached'实体(仅限'已删除')。根据定义,分离的实体不再附加到EntityManager,因此EntityManager不再了解它们。

答案 1 :(得分:0)

我有完全相同的问题。我没有做多对多但仍在单独的entityManager中进行编辑/添加/删除。

我可以确认导出DOES包含已分离的实体,并且在使用MergeStrategy.OverwriteChanges导入主实体管理器时,这些实体会变为分离。

但是,新分离的实体仍然与任何相关实体相关联。

据我所知,重新连接和分离似乎让所有内容都恢复正常:

var result = manager.importEntities(imports);
result.entities
    .filter(function (entity) { return entity.entityAspect.entityState.isDetached(); })
    .forEach(function (entity) { manager.attachEntity(entity); manager.detachEntity(entity); });

Breeze 1.5.3

Github问题与拉请求: https://github.com/Breeze/breeze.js/issues/75

答案 2 :(得分:0)

感谢您发现错误。一个人不应该能够导出或导入一个分离的实体。将来,如果你试图做任何一件事,Breeze会抛出。

现在,我将讨论您的问题,您的目标以及我建议您做的事情。

保存已删除的实体后更新主EntityManager

据我所知,你维护的masterEm只有实体的保存状态。您可以在单独的editEm中制作并保存更改。您导入要更改为editEm的实体,进行更改,保存,以及(如果保存成功),您从editEm导出已保存的实体并将其导回masterEm }。这是一个常见的"沙箱编辑"图案。

editEm 删除 实体时出现问题。保存后,该实体是" Detached"在editEm,但它仍然在"未更改"回到masterEm。如何传达实体被删除的事实并将其从masterEm删除?

  

这种困境独立于多对多"启发你问题的场景。

我可以看到为什么您将从editEm导入现在已分离的实体到masterEm的做法似乎有效。在v.1.5.3中执行该操作会导致masterEm中的相应实体更改为" Detached"国家......这就是你想要的。正如您所看到的,该错误是importEntities方法在导入的实体位于" Detached"中时,没有正确处理导航属性的更新。州。你建议教导importEntities去做正确的事情"在那种情况下。

这里发生的事实是你发现了一个错误。你永远不可能导出一个" Detached"实体,你也不应该导入一个。当你试图导出或导入一个" Detached"时,Breeze应该抛出异常。实体。

有多种原因要求EntityManager导出/导入"分离"实体是个坏主意。我将这些理由解释为另一天。

而不是"解决"导入相关问题" Detached"实体,我们会抛出错误。

这意味着您的部分解决方案将停止工作,让您显然比现在更糟糕。幸运的是,我有另一种方法。我已经编写了这个实用程序函数并对其进行了测试in DocCode

function updateMasterWithSaveResult(masterEm, sourceEm, saveResult) {
  var imports = [];
  var deletes = [];
  saveResult.entities.forEach(function(entity) {
    if (entity.entityAspect.entityState.isDetached()) {
      deletes.push(entity);
    } else {
      imports.push(entity);
    }
  });
  var exported = sourceEm.exportEntities(imports, {
    includeMetadata: false,
    asString: false // as JSON
  });
  masterEm.importEntities(exported);

  deletes.forEach(function(detached) {
    var entity = masterEm.getEntityByKey(detached.entityAspect.getKey());
    entity && entity.entityAspect.setDetached();
  });
}

更新文档

我刚刚将这个添加到我们的"Cool Breeze" documentation几乎逐字。