Caching not working as expected in Kentico 13

Danny Winbourne asked on October 30, 2020 16:05

I am working on a new Kentico 13 project using .NET Core.

I created repository code based off the ArticleRepository.cs file in the .NET Core dancing goat example project. I have the following:

        var page = pageDataContextRetriever.Retrieve<MainPage>().Page;

        return =  pageRetriever.Retrieve<CMS.DocumentEngine.Types.MySite.MainPage>(
            query => query
                .WhereEquals("NodeID", page.NodeID),
            cache => cache
                .Key($"{nameof(MainPageRepository)}|{nameof(GetCurrent)}|{page.NodeID}"))
            .First();

My issue is that the cache is not getting cleared on page save on the front-end website. I am not sure if this is related, but the web farm is running correctly (so far as the web farm application shows no errors).

Any suggestions on what I might be missing?

Correct Answer

Dmitry Bastron answered on October 30, 2020 19:34

Hi Danny,

By default, this cache doesn't contain any cache dependencies. It means if change your MainPage page the system wouldn't know that cache should be cleared. What you need to do is to add .Dependencies(..) into your call. From your example it could be:

var page = pageDataContextRetriever.Retrieve<MainPage>().Page;

return pageRetriever.Retrieve<MainPage>(
        query => query
            .WhereEquals("NodeID", page.NodeID),
        cache => cache
            .Key($"{nameof(MainPageRepository)}|{nameof(GetCurrent)}|{page.NodeID}"))
            .Dependencies((_, builder) => { }, true) // the last param adds default dependencies
        .First();

I haven't tried it myself yet but by the looks of the code it should work. In DancingGoat you may find more .Dependencies call examples which would be very useful to look at. Bear in mind, behind the scenes it uses cache dependency machanism. This ".Dependencies" call is just a nice way of generating those dummy keys automatically.

0 votesVote for this answer Unmark Correct answer

Recent Answers


Sean Wright answered on October 31, 2020 17:39

Like Dmitry mentioned, you'll want to use the .Dependencies() method to specify what content your query depends on (what should invalidate the cache).

There are some default cache dependencies that get set based on the current page, but not based on related pages. This means if you update the page using the content returned by this query, the cache will be cleared, however changes to any other page will not result in a cache eviction without using the .Dependencies() method.

Here are the methods that the 2nd builder parameter of the delegate passed to .Dependencies() exposes:

IPageCacheDependencyBuilder<TPageType> Custom(string key);
IPageCacheDependencyBuilder<TPageType> Objects(IEnumerable<BaseInfo> objects);
IPageCacheDependencyBuilder<TPageType> ObjectType(string objectType);
IPageCacheDependencyBuilder<TPageType> PageOrder();
IPageCacheDependencyBuilder<TPageType> PagePath(string path, PathTypeEnum type = PathTypeEnum.Explicit);
IPageCacheDependencyBuilder<TPageType> Pages(IEnumerable<TreeNode> pages);
IPageCacheDependencyBuilder<TPageType> Pages(string className);
IPageCacheDependencyBuilder<TPageType> PageType(string className);

These don't cover all potential dependencies, but they handle the most common ones. You can use the .Custom() method if you need to handle other dependencies (use this in combination with the 'cache dependency mechanism' link Dmitry supplied).

Also note that the first parameter to the delegate passed to .Dependencies()` is the result of the query, so you can set dependencies on the items your query returns (a pretty common use case).

1 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.