Removing Query Data Cached by the OrganizationServiceContext in Microsoft Dynamics CRM

Visit Website View Our Posts

One of the great set of tools provided by the CRM 2011 SDK are the SDK Extensions which provide the OrganizationServiceContext for accessing data in CRM.  The OrganizationServiceContext provides a way to access CRM and provides features such as change management, exposing an IQueryable interface, implementing a LINQ query provider, and providing caching services.  It is the caching services that I would like to take a look at today.

Most of the time, the caching provided by the OrganizationServiceContext is exactly what you are looking for as a developer.  It provides faster access to the data exposed by the OrganizationService and reduces the load on the network.  However, there are times, when retrieving data that you would like to have a current set of data rather than a set of cached data.  There are a couple of methods that can be employed if you would like to retrieve a set of current data using the OrganizationServiceContext.  One of these is to modify the configuration in the web.config or app.config file that is used to specify how the client context is initialized.  Another is to instantiate the OrganizationServiceContext yourself and pass an instance of a non-caching OrganizationService when constructing the context.

While these methods will work and have their purposes, most of the time I would like to use a caching instance of the OrganizationService but still be able to control the caching so that I can retrieve a current set of data if necessary (I like to have my cake and eat it too).  The great news is that it is possible to control the data caching of the OrganizationServiceContext to some extent if you understand the structure of the context class that is being used.

If you are using early binding and the CrmSvcUtil.exe to generate an OrganizationServiceContext to be used when accessing data in CRM, the class that gets generated derives from the CrmOrganizationServiceContext.  If you are using late binding you will more than likely be using the CrmOrganizationServiceContext directly.  The CrmOrganizationServiceContext implements the IOrganizationServiceContainer interface that exposes a Service property.  If you have not specified a type for the service to be used by the context, this object will be an instance of the CachedOrganizationService.  In addition, the CachedOrganizationService class exposes a Cache property that is an IOrganizationServiceCache instance.  It is this instance of the IOrganizationServiceCache that exposes the methods that allow items to be removed from the cached used by the context.

Now that we have an understanding of the structure of the context it is simple to write an extension method that will remove cached data items.  The following snippet of code can be used to remove entity data from the set of data cached by the context.

 1: public void RemoveCachedData(OrganizationServiceContext context, string entityLogicalName, Guid? id) {
 3:     var serviceContainer = context as IOrganizationServiceContainer;
 4:     if (serviceContainer == null) {
 5:         return;
 6:     }
 8:     var cachedOrgService = serviceContainer.Service as CachedOrganizationService;
 9:     if (cachedOrgService == null) {
 10:         return;
 11:     }
 13:     var orgServiceCache = cachedOrgService.Cache as IOrganizationServiceCache;
 14:     if (orgServiceCache == null) {
 15:         return;
 16:     }
 18:     orgServiceCache.Remove(entityLogicalName, id);
 19: }

As you can see, we simply need to cast the context to an IOrganizationServiceContainer and drill down through the object until we get at the actual OrganizationServiceCache.  Once we have an instance of the OrganizationServiceCache we can use one of the Remove methods to remove the cached data.  There are several other overloaded Remove methods that allow data to be removed and I have only shown one of them that will allow data to be removed for a specific entity.  In the snippet I have shown, if the id argument is not supplied, any cached data for the specified entity will be removed.

Now all that needs to be done is call the method to remove the cached data before executing your query to retrieve data.  If you would like to remove other pieces of cached data you can browse the CRM 2011 SDK and have a look at the Remove methods exposed by the OrganizationServiceCache class.

Post by: Nick Doriot, Customer Effective

Show Buttons
Hide Buttons