Breeze - 已删除项目导航属性错误

时间:2014-04-24 16:45:22

标签: breeze

根据breeze api,当调用setDeleted时,它将从所有相关实体中删除实体。这是事实,但使用实体管理器的importEntities函数导入已删除的项目时,行为存在缺陷。已删除的实体将清空其导航属性,但具有包含已删除项目的导航属性的其他实体将该项目保留在其导航列表中。如果在实体上调用setDeleted,即使它已被删除,它也会解决问题,但这不是必需的。

我已经为DocCode测试创建了这个测试用例。

/*********************************************************
    * Create an EM with parent/child relationship data.  Export the EM and import it into a new one, delete the child item in the exported EM
    * export the 2nd EM into the first EM.
    *********************************************************/
    test("test imported deleted nav properties", 2, function () {
        var em = newEm();

        // create a new parent Customer
        var parentCustomer = em.createEntity("Customer", {
            CustomerID: dummyCustID,
            CompanyName: 'TestCo'
        });

        // a new Order which is a child of the parent Customer
        var newOrder = em.createEntity("Order", {
            CustomerID: parentCustomer.CustomerID()
        });
        parentCustomer.entityAspect.setUnchanged();
        newOrder.entityAspect.setUnchanged();

        // clone the EM data
        var expEntities = em.exportEntities(null, true);

        //var newEm = newEm();
        var newEM = new breeze.EntityManager();
        newEM.importEntities(expEntities, { mergeStrategy: breeze.MergeStrategy.OverwriteChanges });

        // delete the order
        var newOrderCopy = newEM.getEntities("Order")[0];
        newOrderCopy.entityAspect.setDeleted();

        // export the cloned EM
        var expEntitiesNew = newEM.exportEntities();
        // merge to the original EM
        em.importEntities(expEntitiesNew, { mergeStrategy: breeze.MergeStrategy.OverwriteChanges });

        var deletedOrder = parentCustomer.Orders();

        ok(newOrder.entityAspect.entityState.isDeleted(), "newOrder should be 'deleted'");
        ok(deletedOrder.length === 0, "parentCustomer's 'Orders' should be empty");
    });

2 个答案:

答案 0 :(得分:0)

Breeze文档描述了沙盒编辑的概念(http://www.getbreezenow.com/documentation/multiple-managers)。我想在模态对话框中应用这个概念。仅当用户单击确定按钮时,才应在主窗口中接受其更改。当她点击取消按钮时,她的更改应该被删除。

以下是步骤:

  • 创建新的EntityManager(沙盒)
  • 使用应在对话框中显示或更改的实体填充Sandbox EntityManager。
  • 打开对话框并移交Sandbox EntityManager。
  • 当用户单击确定按钮时,从Sandbox EntityManager导出所有已更改,添加和删除的实体,并将它们导入主EntityManager或父EntityManager。
  • 当用户点击取消按钮时,单独离开Sandbox EntityManager并让垃圾收集器完成工作。

在将已删除的实体转移回主要或父EntityManager时,我遇到了与此处描述的完全相同的问题。

var deletedEntities = sandboxEm.getEntities(breeze.EntityState.Deleted);
var deletedEntitiesExport = sandboxEm.exportEntities(deletedEntities, false);
mainEm.importEntities(deletedEntitiesExport).entities;

导入的实体被标记为已删除(EntityState已删除),但不会删除相关实体的导航属性。

tsdude推荐的解决方法为我工作:

var deletedEntities = sandboxEm.getEntities(breeze.EntityState.Deleted);
var deletedEntitiesExport = sandboxEm.exportEntities(deletedEntities, false);
var deleted = mainEm.importEntities(deletedEntitiesExport).entities;

// without effect :-(
deleted.forEach(function (e) {
    e.entityAspect.setDeleted();
});

我能够在不导入已删除实体的情况下完成此操作。我遍历已删除的实体,并将主要EntityManger中的对应项明确标记为已删除:

sandboxEm.getEntities(breeze.EntityState.Deleted).forEach(function (deleted) {
    var key = deleted.entityAspect.getKey();
    var e = mainEm.getEntityByKey(key);
    e.entityAspect.setDeleted();
});

注意:Breeze版本是1.5.2。

答案 1 :(得分:0)

很抱歉这么长时间,这个滑倒了。

这是一个错误,现在已在GitHub仓库中修复。它也将在1.5.3版本中发布。 ...并感谢repro。