locked
LINQ to CRM Caching issue? RRS feed

  • Question

  • I'm wondering how you would go about resetting/refreshing the cache on LINQ to CRM queries. The first time a query is performed, the correct data is returned, but if I go back and change some values on a record and rerun the query, the original values are returned. There isn't much out there on this but it seems that the queries are cached.

    I've read here http://www.xrmlinq.com/crm-sdk-4-0-12-bugs-limitations/ that there is no way to turn off the caching but need to "explicitly call a Remove method on the cache manager", but I can't find any documentation on how to accomplish this.

    Has anyone come up against this or have any ideas to work around?

    Thanks.

    Thursday, June 3, 2010 3:24 PM

Answers

  • actually it has nothing to do with System.Web.HttpContext.Current.Cache System.Web.HttpContext.Current.Cache

     

    just tested the code snippet blew and worked correctly.

    public static void ClearCache(string entityName)
           {
               const string format = "adxdependency:crm:entity:{0}";
               var dependency = string.Format(format, entityName).ToLower();

               var cache = Microsoft.Xrm.Client.Caching.CacheManager.GetBaseCache();
               cache.Remove(dependency);
           }

    • Proposed as answer by Sebastian W Monday, June 7, 2010 12:31 PM
    • Marked as answer by Jim Glass Jr Monday, June 7, 2010 2:33 PM
    Monday, June 7, 2010 11:53 AM
  • You can use that extension method its safer that way

    static public class CacheExt
    {
        public static void Clear(this Cache x)
        {
            List<string> cacheKeys = new List<string>();
            IDictionaryEnumerator cacheEnum = x.GetEnumerator();
            while (cacheEnum.MoveNext())
            {
                cacheKeys.Add(cacheEnum.Key.ToString());
            }
            foreach (string cacheKey in cacheKeys)
            {
                x.Remove(cacheKey);
            }
        }
    }
    • Marked as answer by Jim Glass Jr Monday, June 7, 2010 2:33 PM
    Friday, June 4, 2010 2:52 PM

All replies

  • Hi

    I was playing with that today and I can share my results. I had iframe with custom web app which shows appoitments . very simple stuff

     

    activitiesGridView.DataSource =
               (from app in crm.GetEntities("appointment")
                where app.GetPropertyValue<Guid>("regardingobjectid") == servicerequestId
                && app.GetPropertyValue<string>("statecode") == "Scheduled"
                select app);
        activitiesGridView.DataBind();

    Of course when you load form with that iframe shows only appoitments which were already in system when you add new one and refresh form/iframe the new ones are not printed . I dig a bit and I found very dirty trick.

     Cache.Remove(cachekey);
    

    Rubbish :) If someone has found beter way of handling that please share :)  It's  exacly what you quoted . I'll do more digging later but I'd like to have the others opinions.

    Best Regards

    SW

    PS

    I know that funcionality can be achived in many diffrent ways i.e  fetchxml but this is not how to do it but why how to do it properly in new XRM.SDK . 

    Thursday, June 3, 2010 8:46 PM
  • Sebastian,

    I think from what I've read, that "dirty trick" is the best work around for now, and until something better comes along, will solve my problem.

    Could you tell me, how do you determine which key you need to remove from the cache?
    Cache.Remove(cachekey);  <- Where do you get the value for "cachekey"?

    Thanks

    Friday, June 4, 2010 2:24 PM
  • Could you tell me, how do you determine which key you need to remove from the cache?
    Cache.Remove(cachekey);  <- Where do you get the value for "cachekey"?

    Check that code bellow  I haven't explore that fully when I'll have a time I'll do more testing

      IDictionaryEnumerator CacheEnum = Cache.GetEnumerator();
          while (CacheEnum.MoveNext())
          {
            //look for the key or clear all cache :) 
            // Keyname = CacheEnum.Key.ToString())
            
                    Cache.Remove(key...) }

    Well  this is my personal opinion  but I think this release it not ready to use with live systems  let's wait for next one I hope it will be at some point :)

    Best Regards

    SW

    Friday, June 4, 2010 2:39 PM
  • You can use that extension method its safer that way

    static public class CacheExt
    {
        public static void Clear(this Cache x)
        {
            List<string> cacheKeys = new List<string>();
            IDictionaryEnumerator cacheEnum = x.GetEnumerator();
            while (cacheEnum.MoveNext())
            {
                cacheKeys.Add(cacheEnum.Key.ToString());
            }
            foreach (string cacheKey in cacheKeys)
            {
                x.Remove(cacheKey);
            }
        }
    }
    • Marked as answer by Jim Glass Jr Monday, June 7, 2010 2:33 PM
    Friday, June 4, 2010 2:52 PM
  • Thanks :)

    Based on the information you gave me and the code found here

    http://community.adxstudio.com/Default.aspx?DN=d589dc6c-b2bf-4ae1-a8ca-06ac55f2a177&topic=95c3b0f5-8bc8-433d-90cb-d501ce17f4ad&page=1 

    I was able to come up with a half way decent (if not ideal) solution for now.

     

     

    public static void ClearCache(string entityName)
        {
          const string format = "adxdependency:crm:entity:{0}";  
          var dependency = string.Format(format, entityName).ToLower(); 
    
          System.Web.HttpContext.Current.Cache.Remove(dependency); 
        }

    Passing the entityName removes all related cache items for that entity.

     

    Friday, June 4, 2010 3:58 PM
  • Thx Yes I was concern about clearing all cache but that looks not that bad :)  I hope next ver will have basically nice method  to refresh entity or parametr.

    Regards

    SW 

     

    Friday, June 4, 2010 4:53 PM
  • actually it has nothing to do with System.Web.HttpContext.Current.Cache System.Web.HttpContext.Current.Cache

     

    just tested the code snippet blew and worked correctly.

    public static void ClearCache(string entityName)
           {
               const string format = "adxdependency:crm:entity:{0}";
               var dependency = string.Format(format, entityName).ToLower();

               var cache = Microsoft.Xrm.Client.Caching.CacheManager.GetBaseCache();
               cache.Remove(dependency);
           }

    • Proposed as answer by Sebastian W Monday, June 7, 2010 12:31 PM
    • Marked as answer by Jim Glass Jr Monday, June 7, 2010 2:33 PM
    Monday, June 7, 2010 11:53 AM
  • Good stuff SW
    Monday, June 7, 2010 12:30 PM
  • Thanks to you all for this discussion. I have the same cache problem, the ClearCache (entityName) function solved it. Why did such a droppings fall to release?
    An apple a day keeps the doctor away
    Thursday, July 1, 2010 8:11 AM
  • Awesome, thanks. If you're using a WCF Data Service, you can put this method in the Data Service, along with the InitializeService method. Then, call it from the InitializeService method, and then all of the calls you make to your data service should be unchached.


    Web: http://invoc.net Blog: http://invoc.net/CRM_BPOS_Blog
    Saturday, July 24, 2010 8:57 PM
  • How will i get entity name thru the WCF Data Service? also in the adxstudio community post it says that caching can be disabled by //context.CacheResults = false;

    did anyone try that? are they using asp.net cache?

    Tuesday, August 10, 2010 10:20 PM
  • Hi Mohamed,

    I've put this in the actual dataservice.cs file. I've actually found that it worked with one dataservice I created, and not another.


    Web: http://invoc.net Blog: http://invoc.net/CRM_BPOS_Blog
    Wednesday, August 11, 2010 6:01 PM
  • u mean u used the context.CacheResults = false?

    I don't see obvious way to get entity name to clear its cache version with the method mentioned above?

    Wednesday, August 11, 2010 7:51 PM
  • Hello all,

     

    Offcourse i'm strugling with the same problem and whant  to use the above mentioned sollution.

    But does anyone know how to  search/collect the entity Names that need cleaning/removing.

    We are using quit a couple of entities and it's not that clear witch ones are used besides the ones found in our queries.

    Thanks

     

     

    Thursday, August 12, 2010 8:49 AM
  • i got it to work like this in the WCF Data Service.

    private static void ClearCache(string entityName)
            {
                const string format = "adxdependency:crm:entity:{0}";
                var dependency = string.Format(format, entityName).ToLower();

                var cache = Microsoft.Xrm.Client.Caching.CacheManager.GetBaseCache();
                cache.Remove(dependency);
            }
            [QueryInterceptor("Customers")]
            public Expression<Func<Customer, bool>> QueryCustomers()
            {
                ClearCache("account");
        //return true.
                return c=> 1 == 1;
            }
            [QueryInterceptor("Products")]
            public Expression<Func<Product, bool>> QueryProducts()
            {
                ClearCache("product");
                return c => 1 == 1;
            }

    Thursday, August 12, 2010 8:14 PM
  • Thanks man,

    Last version and of course you can clear all cache with Clear() or RemoveAll()

            public static void ClearCache(string entityName)
            {
                var dependency = String.Format("xrm:dependency:entity:{0}", entityName).ToLower();
                var cache = Microsoft.Xrm.Client.Caching.ObjectCacheManager.GetInstance(null);
                cache.Remove(dependency);
            }

    Saturday, September 8, 2012 5:38 AM