TL: DR
Never set the FK in the createEntity initializer, and also redirect the object to the parent navigation property. Supports either of them, but not both.
Basic principles
After you come across a similar problem and have done a lot of research, I would like to offer an alternative answer. The problem you're experimenting with is not how you delete the item, but how to create the item.
A breeze is very useful when it comes to managing data context. He knows about navigation properties and foreign keys and how to handle them. As a side effect of the local data context, all observables also have this intelligence. This is the place where you probably missed something and ran into this problem.
Breeze Tracking Code
What does all this mean specifically? Well, there are two ways you can use to create an object with a parent using the breeze. The first is to set the parent identifier in the initializer, for example:
var c = manager.createEntity('contact', { 'donorId': 12, 'name': 'bob' });
Another is to add an object to the navigation property in the parent object in the context of the breeze data.
var parents = ko.observableArray(); manager.runQuery(..., parents); var c = manager.createEntity('contact', { 'name': 'bob'}); parents.contacts.push(c);
Both cases have their pros and cons. The problem arises when you try to do both:
var parents = ko.observableArray(); manager.runQuery(..., parents); var c = manager.createEntity('contact', { 'donorId': 12, 'name': 'bob' }); parents.contacts.push(c);
Breeze tries to optimize its queries when working with inserts to prevent the user interface from flickering. When push
called, it disables notifications on the target observable until the entire operation is completed. Then it will call valueHasMutated
internally, which will result in a UI update. The fact is that a call to createEntity
interferes with this mechanism and causes the notification to be reinitialized too soon. Then push
save this invalid state, replace it and reset to it, leaving the observable in the invalid state.
When you ultimately call setDeleted
, notifications will still be turned off at an observable level, preventing the user interface from updating, even if the data is correctly inserted into the breeze data context. This will happen only once after inserting a new item. Deleting an element will cause the state to change to its correct value, and all subsequent deletion in the navigation property will cause the interface to be updated.
Looking at your two options
In the end, you should use setDeleted
to properly remove the object from the wind navigation property. There is no need to remove it from the manually observable, and in fact it will reset the foreign key for null
, which can cause problems of deserialization on the server if the type cannot be null in your model or errors when trying to delete a row from the database depending on how your primary key is determined. Option B is the one to go with.