I have noticed an irksome discrepancy in Breeze.js between deleting a not yet persisted entity (EntityState = "Added") and a persisted entity with respect to any references to it (foreign keys).
This may be an issue related to generating temporary keys for new entities. In this case, we generate negative numbers for temporary keys (ids), replaced with the actual keys when they are persisted.
This will be more easily explained with a concrete example. Say we have an entity called Person that holds a reference to a Title entity ("Mr", "Mrs", etc):
export class Person extends EntityBase {
id: number;
firstName: string;
lastName: string;
titleId: number;
title: Title;
...
}
export class Title extends EntityBase {
id: number;
name: string;
...
}
Now, if we have a persisted Title entity in our current context and call .setDeleted() on it, both the titleId property and the title navigation property on applicable Person entities are set to null.
If, however, the Title entity has an EntityState of "Added", only the title navigation property on all linked Person entities is set to null. The titleId property retains its value, leading to an error when saving (a foreign key constraint violation).
This means that deleting a Title entity with an EntityState of "Added" requires explicitly setting the titleId property to null for all linked Person entities.
It is perhaps worth noting that the TitleID column in the underlying database is nullable. If it were not, we would, of course, have to set the titleId property to a suitable value.
It seems clumsy to have to do this. Is this behavior intentional, for some reason that escapes me?
When it comes to deletes, Breeze makes an important distinction between
For an already-persisted entity (case b), Breeze must keep track of that deleted entity, and send the deletion to the server. Any foreign keys on the server must be updated to remove references to the deleted entity, so breeze updates the related client entities accordingly and sends those changes to the server as well.
For a newly-created entity (case a), the server knows nothing about it. When it is
"deleted" on the client, Breeze doesn't actually set it Deleted
, because it doesn't
need to send a deletion to the server. Instead, it sets it Detached
.
When an entity is set Detached
, its navigation properties are set to null, and it
is removed from the EntityManager's cache. Its foreign key properties are not changed,
however, so if you detach an entity and re-attach it, the navigation properties will
be reconnected. This is true whether the entity was Added
or any other state before
it became Detached
.
More about the entity states can be found in the Breeze documentation