Breeze EntityManager 没有删除导入的分离实体?
Breeze EntityManager not removing imported detached entites?
我正在使用 Wards excellent example 通过 breeze 实现多对多。 (我要在他的 post 中大放异彩,不能 link 从这里不知道为什么)
一切正常,更改始终正确保存到数据库。
我正在使用 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});
}
请使用最新发布的 breeze (1.5.3) 版本试试。那里修复了一个非常相似的错误。
需要说明的是,导出永远不能包含 'detached' 个实体(仅 'deleted' 个)。根据定义,分离的实体不再附加到 EntityManager,因此 EntityManager 不再了解它们。
我遇到了完全相同的问题。我没有做 many-to-many,但仍在单独的 entityManager 中做 edits/adds/deletes。
我可以确认导出确实包括分离的实体,并且在使用 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
感谢您发现错误。人们不应该能够导出或导入一个分离的实体。将来,如果您尝试执行任一操作,Breeze 都会抛出异常。
现在我将讨论您的问题、您的目标以及我建议您做的事情。
保存删除的实体后更新主 EntityManager
据我了解,您维护了一个 masterEm
,它只有实体的保存状态。您在单独的 editEm
中进行更改并保存。您将要更改的实体导入 editEm
,进行更改,保存它们,然后(如果保存成功),从 editEm
导出保存的实体并将它们导入回 masterEm
.这是一种常见的“沙盒编辑”模式。
当您删除 editEm
中的实体时出现问题。保存后,该实体在 editEm
中处于“分离”状态,但在 masterEm
中仍处于“未更改”状态。您如何传达实体已删除并将其从 masterEm
中删除的事实?
This dilemma exists independent of the "many-to-many" scenario that inspired your question.
我明白为什么您将现在分离的实体从 editEm
导入到 masterEm
的做法似乎有效。在 v.1.5.3 中这样做会导致 masterEm
中的相应实体更改为“分离”状态……这就是您想要的。如您所见,该错误是当导入的实体处于“分离”状态时,importEntities
方法无法正确处理导航属性的更新。您建议教 importEntities
在那种情况下“做正确的事”。
这里实际发生的是您发现了一个错误。您永远不应该能够导出“分离”实体,也不应该能够导入一个实体。当您尝试导出或导入“分离”实体时,Breeze 应该会抛出异常。
为什么要求 EntityManager
到 export/import“分离的”实体不是一个好主意的原因有很多。我将在另一天解释这些原因。
我们不会“解决”导入相关“分离”实体的问题,而是抛出一个错误。
这意味着您的部分解决方案将停止工作,使您显然比今天更糟。幸运的是,我为您提供了另一种方法。我已经编写了这个效用函数并对其进行了测试 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 中。
我正在使用 Wards excellent example 通过 breeze 实现多对多。 (我要在他的 post 中大放异彩,不能 link 从这里不知道为什么)
一切正常,更改始终正确保存到数据库。
我正在使用 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});
}
请使用最新发布的 breeze (1.5.3) 版本试试。那里修复了一个非常相似的错误。
需要说明的是,导出永远不能包含 'detached' 个实体(仅 'deleted' 个)。根据定义,分离的实体不再附加到 EntityManager,因此 EntityManager 不再了解它们。
我遇到了完全相同的问题。我没有做 many-to-many,但仍在单独的 entityManager 中做 edits/adds/deletes。
我可以确认导出确实包括分离的实体,并且在使用 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
感谢您发现错误。人们不应该能够导出或导入一个分离的实体。将来,如果您尝试执行任一操作,Breeze 都会抛出异常。
现在我将讨论您的问题、您的目标以及我建议您做的事情。
保存删除的实体后更新主 EntityManager
据我了解,您维护了一个 masterEm
,它只有实体的保存状态。您在单独的 editEm
中进行更改并保存。您将要更改的实体导入 editEm
,进行更改,保存它们,然后(如果保存成功),从 editEm
导出保存的实体并将它们导入回 masterEm
.这是一种常见的“沙盒编辑”模式。
当您删除 editEm
中的实体时出现问题。保存后,该实体在 editEm
中处于“分离”状态,但在 masterEm
中仍处于“未更改”状态。您如何传达实体已删除并将其从 masterEm
中删除的事实?
This dilemma exists independent of the "many-to-many" scenario that inspired your question.
我明白为什么您将现在分离的实体从 editEm
导入到 masterEm
的做法似乎有效。在 v.1.5.3 中这样做会导致 masterEm
中的相应实体更改为“分离”状态……这就是您想要的。如您所见,该错误是当导入的实体处于“分离”状态时,importEntities
方法无法正确处理导航属性的更新。您建议教 importEntities
在那种情况下“做正确的事”。
这里实际发生的是您发现了一个错误。您永远不应该能够导出“分离”实体,也不应该能够导入一个实体。当您尝试导出或导入“分离”实体时,Breeze 应该会抛出异常。
为什么要求 EntityManager
到 export/import“分离的”实体不是一个好主意的原因有很多。我将在另一天解释这些原因。
我们不会“解决”导入相关“分离”实体的问题,而是抛出一个错误。
这意味着您的部分解决方案将停止工作,使您显然比今天更糟。幸运的是,我为您提供了另一种方法。我已经编写了这个效用函数并对其进行了测试 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 中。