Caching a custom function

MJ FV asked on July 15, 2015 18:32

I have this function:

public static string GetCategory(int documentId)
    {
        if (documentId < 1)
        {
            throw new Exception("Invalid document ID");
        }      
        DataSet ds = CategoryInfoProvider.GetDocumentCategories(documentId, "CategoryNamePath LIKE '/type/%'", "CategoryOrder ASC", 1, "CMS_Category.CategoryID, CategoryDisplayName, CategoryNamePath, CategoryOrder");
        if (!DataHelper.DataSourceIsEmpty(ds))
        {
            return ValidationHelper.GetString(ds.Tables[0].Rows[0]["CategoryDisplayName"], null);
        }

        return string.Empty;
    }

This is to add the category name to a transformation. The problem is that the function does 40+ queries to DB, and we wanted to cache it. I tried a lot of things, but nothing seems to work.

Any help appreciated.

Recent Answers


Brenden Kehren answered on July 15, 2015 18:45

Check out the documentation on Caching in Kentico.

0 votesVote for this answer Mark as a Correct answer

MJ FV answered on July 15, 2015 18:50

Already been there. What i don't get, is how i get from what is in the documentation to what i have.

I saw this other site also

http://bitwizards.com/blog/march-2014/how-to-leverage-the-kentico-caching-api-in-your-co?eid=3

and tried to do something similar:

public static string GetCategory(int documentId) { if (documentId < 1) { throw new Exception("Invalid document ID"); } int cacheMinutes = SettingsKeyInfoProvider.GetIntValue(SiteContext.CurrentSiteName + ".CMSCacheMinutes");

    DataSet docscat = null;

    using (var cs = new CachedSection<DataSet>(ref docscat, cacheMinutes, true, null, "categorycache"))
    {
        if (cs.LoadData)
        {
            docscat = CategoryInfoProvider.GetDocumentCategories(documentId, "CategoryNamePath LIKE '/Type/%'", "CategoryOrder ASC", 100, "CMS_Category.CategoryID, CategoryDisplayName, CategoryNamePath, CategoryOrder");

            cs.Data = docscat;

            return ValidationHelper.GetString(docscat.Tables[0].Rows[0]["CategoryDisplayName"], null);
        }
        return ValidationHelper.GetString(cs.GetData().Tables[0].Rows[0]["CategoryDisplayName"], null);
    }
}

The problem is that it only IF(cs.LoadData) only runs once, so i only get one category, instead of the 40+

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on July 15, 2015 20:53

So you have a listing of pages/documents you want to get categories they are assigned/related to, correct? If so, then I'm not 100% sure this will work as you're expecting without having a cached dataset for each documentid.

So in your loop, document 100 is getting 5 categories, and then when the function is called again for document 101, it needs to get 10 categories but since that cached dataset is already cached, it won't get it again. You need to have a unique cache key for each document ID I believe vs. "categorycache".

0 votesVote for this answer Mark as a Correct answer

Bill Tran answered on August 14, 2015 19:10 (last edited on August 14, 2015 19:22)

You can use the HttpContext.Current.Items to store the results in memory, and work with it.

public static string GetCategory(int documentId) { if (documentId < 1) { throw new Exception("Invalid document ID"); }

    DataSet ds = null;

    if (HttpContext.Current.Items["MyDataSet"] == null)
    {
        ds = CategoryInfoProvider.GetDocumentCategories(documentId, "CategoryNamePath LIKE '/type/%'", "CategoryOrder ASC", 1, "CMS_Category.CategoryID, CategoryDisplayName, CategoryNamePath, CategoryOrder");
    }
    else
    {
        ds = (DataSet)HttpContext.Current.Items["MyDataSet"];
    }
    return string.Empty;
}
0 votesVote for this answer Mark as a Correct answer

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