Refresh the cached EntitySet after a SubmitChanges – WCF RIA Services
Note: This post is based on the WCF RIA Services PDC Beta.
There is a discussion about WCR RIA Services and how to update an EntitySet after a Submit changes, on the Silverlight forum. If we loads a set of entities they will be cached in an EntitySet on the client-side, so after a Submitting changes only the entities we have removed on the client will be removed from the client-side’s EntitySet. If someone else have removed some of the entities from the database we work against, we still have those cached on the client-side. At the moment there aren’t any reload features added to the WCF RIA Services, so we need to handle it by our self. We can’t just make a new call to the Load method of our DomainContext, it will only “merge” the existing EntitySet with changes or add new entities, but not removing anything. So what we need to do, is to implement code which will handle the removing of entites from the EntitySet. Here is an example code which will make sure removed entities (entities which is cached since an early Load operation but not part of the new Load operation) will be removed from the cached EntitySet:
_domainContext.SubmitChanges( submitOperation => { _domainContext.Load<Customer>( _domainContext.GetCustomersQuery(), LoadBehavior.RefreshCurrent, loadOperation => { var results = _domainContext.Customers.Where( entity => !loadOperation.Entities.Contains(entity)).ToList(); results.ForEach( enitity => _domainContext.Customers.Detach(entity)); }, null); }, null);
The above code will after a SubmitChanges Load new entities from the server. The LoadBehavior is set to RefreshCurrent, it will make sure to refresh the current entities in the cached EntitySet, but will not remove anything. When the Load operation is completed and we got the new entities from the server, we then need to get the entities which is not part of the last Loading from the cached EnitySet:
var results = _domainContext.Customers.Where( entity => !loadOperation.Entities.Contains(entity)).ToList();
Then we need to Detach the entities from the EntitySet. We can’t use the Remove method of the EntitySet, it will only mark entities for deletion. But the Detach method will not mark them and just remove them form the EntityList.
results.ForEach( enitity => _domainContext.Customers.Detach(entity));
We could also just clear the EntitySet buy setting using its Clear method before calling the Load method, but if we have bound the EntitySet to a data-bound control,the control will be notified when the EntitySet is cleared. That will make it “blink”. With the above solution there will not be any blinking.
I will not take all the credits for the solution in this blog post, I will thank Colin Blair for the basic ideas of removing entities from the EntitySet. In the future I hope we will se some other solution with less efforts.
If you want to know when I publish a new blog post, you can follow me on twitter: http://www.twitter.com/fredrikn