问题
According to the breeze api, when setDeleted is called, it will remove the entity from all the related entities. This is true, but the behavior is flawed when importing a deleted item using the entity manager's importEntities function. The deleted entity will have it's navigational properties emptied, but other entities that have navigational properties containing the deleted item will keep that item in their nav lists. If setDeleted is called on the entity, even though it is already deleted, it will fix the problem, but this should not be necessary.
I've created this test case for the DocCode tests.
/*********************************************************
* 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");
});
回答1:
The Breeze docu describes the concept of Sandbox Editing (http://www.getbreezenow.com/documentation/multiple-managers). I wanted to apply this concept on a modal dialog. Only when the user clicks the ok button her changes should be accepted in the main window. When she clicks the cancel button her changes should be dropped.
These are the steps:
- Create a new EntityManager (Sandbox)
- Fill the Sandbox EntityManager with entities that should be displayed or changed in the dialog.
- Open the dialog and hand over the Sandbox EntityManager.
- When the user clicks the ok button export all changed, added and deleted entities from the Sandbox EntityManager and import them into the main or parent EntityManager.
- When the user clicks the cancel button leave the Sandbox EntityManager alone and let the garbage collector do the work.
While transfering back the deleted entities into the main or parent EntityManager I ran into the exact same problem which is described here.
var deletedEntities = sandboxEm.getEntities(breeze.EntityState.Deleted);
var deletedEntitiesExport = sandboxEm.exportEntities(deletedEntities, false);
mainEm.importEntities(deletedEntitiesExport).entities;
The imported entities are marked as deleted (EntityState is Deleted) but they are not removed for the navigation properties of related entities.
The workaround recommended by tsdude did not work for me:
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();
});
I was able to do it without importing the deleted entities. I iterate over the deleted entities and mark there counterparts in the main EntityManger explicitly as deleted:
sandboxEm.getEntities(breeze.EntityState.Deleted).forEach(function (deleted) {
var key = deleted.entityAspect.getKey();
var e = mainEm.getEntityByKey(key);
e.entityAspect.setDeleted();
});
Note: The Breeze version is 1.5.2.
回答2:
Sorry for taking so long, this one slipped through.
It was a bug and is now fixed in the GitHub repo. It will also go out in the 1.5.3 release. ... and thanks for the repro.
来源:https://stackoverflow.com/questions/23274992/breeze-deleted-items-nav-properties-bug