I have this issue with a breeze entity and its navigation properties, which get populated through a WebAPI call.
return EntityQuery.from('UserInfo')
.withParameters({ clientId: clientId, userId: userId })
.using(self.manager)
.execute()
.then(querySucceeded, this._queryFailed);
function querySucceeded(data) {
return data.results[0];
}
Here's the sequence of events that take place.
The problem is - in the second UserInfo API call, on the breeze query side, I can see 3 userWorkLocation objects (see the screenshot).
But I inspected the response on the developer tools, and only two userWorkLocation objects are there in the response (see the screenshot). .
Here's the server side code which removes the userworklocation in #3.
if (activeStatus != location.ActiveStatus && location.ActiveStatus == 0)
{
// remove all work location assignments
ClientContext.UserWorkLocations.RemoveRange(ClientContext.UserWorkLocations.Where(u => u.FkLocationId == location.LocationId));
}
ClientContext.SaveChanges();
I put a breakpoint on the server side call and also ensured it returns two. I can't understand how breeze reads 3 objects in the collection, the additional one being the one I deleted. Possibly caching? How do I work around it?
The normal flow with Breeze is that deletions happen on the client and are communicated to the server. The problem here is that Breeze doesn't know about deletions that have happened on the server. It's a classic cache-coherence problem.
There are basically three approaches for solving this:
Clear the cache of the entities or entity types that you suspect to have been deleted, then re-query them. This approach is discussed in some depth in Keeping a fresh cache.
Use soft deletes, in which each entity has a flag (in the code and the database) that indicates deletion. Entities are not really deleted, they are marked so that the client does not display them. If an entity is deleted on the server, the "deleted" flag would be true when the client next queries the entity.
Communicate deletions from the server. During a save, this is facilitated by the deletedKeys
property of the saveResult, an example of which is in the Saving Changes page. The Breeze EntityManager automatically uses deletedKeys
to delete entities that are in the cache. Outside of a save, you would need some other communication between client and server to inform the client about the deletions, such as SignalR.
Each method has its challenges, so you'll need to choose what works best for your application.