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

5 Comments

  • Hi Fredrik,

    Thanks a lot for this post!

    I hope the next one will be about WCF RIA Services exception handling
    best practice for the different type of methods. Currently the Load method, for example, has three more overloads which reflects this issue. You had your previous post about this for RIA .NET. What is major differences?

    Thanks!

  • Thx a lot for this post!

    Been searching for this for a while now but didn't know about this overload!

  • Hi, could you possible submit a sample of this implementation?

  • Fredrik,

    Thank you so much for the post. that helps a lot!

  • I had a very similar problem in that changes I made in a child table in the database wasn't being updated in the client even though a fiddler trace showed the data as coming from the server.

    I just created a partial class based on the client-side domain context class generated by RIA Services. In this class I overrode the load operation to just refresh every single
    time kinda like the pragma no-cache we all love from our webpages.


    public override LoadOperation Load(EntityQuery query,
    LoadBehavior loadBehavior, Action callback, object userState)
    {
    // we want to always replace what we have so force the load behavior to be refresh
    return base.Load(query, LoadBehavior.RefreshCurrent, callback, userState);
    }

Comments have been disabled for this content.