Dowemo
0 0 0 0


Question:

I have read lots of information about page caching and partial page caching in a MVC application. However, I would like to know how you would cache data.

In my scenario I will be using LINQ to Entities (entity framework). On the first call to GetNames (or whatever the method is) I want to grab the data from the database. I want to save the results in cache and on the second call to use the cached version if it exists.

Can anyone show an example of how this would work, where this should be implemented (model?) and if it would work.

I have seen this done in traditional ASP.NET apps , typically for very static data.


Best Answer:


Extending @Hrvoje Hudo's answer...

Code:

using System;
using System.Runtime.Caching;
public class InMemoryCache : ICacheService
{
    public TValue Get<TValue>(string cacheKey, int durationInMinutes, Func<TValue> getItemCallback) where TValue : class
    {
        TValue item = MemoryCache.Default.Get(cacheKey) as TValue;
        if (item == null)
        {
            item = getItemCallback();
            MemoryCache.Default.Add(cacheKey, item, DateTime.Now.AddMinutes(durationInMinutes));
        }
        return item;
    }
    public TValue Get<TValue, TId>(string cacheKeyFormat, TId id, int durationInMinutes, Func<TId, TValue> getItemCallback) where TValue : class
    {
        string cacheKey = string.Format(cacheKeyFormat, id);
        TValue item = MemoryCache.Default.Get(cacheKey) as TValue;
        if (item == null)
        {
            item = getItemCallback(id);
            MemoryCache.Default.Add(cacheKey, item, DateTime.Now.AddMinutes(durationInMinutes));
        }
        return item;
    }
}
interface ICacheService
{
    TValue Get<TValue>(string cacheKey, Func<TValue> getItemCallback) where TValue : class;
    TValue Get<TValue, TId>(string cacheKeyFormat, TId id, Func<TId, TValue> getItemCallback) where TValue : class;
}

Examples

Single item caching (when each item is cached based on its ID because caching the entire catalog for the item type would be too intensive).

Product product = cache.Get("product_{0}", productId, 10, productData.getProductById);

Caching all of something

IEnumerable<Categories> categories = cache.Get("categories", 20, categoryData.getCategories);

Why TId

The second helper is especially nice because most data keys are not composite. Additional methods could be added if you use composite keys often. In this way you avoid doing all sorts of string concatenation or string.Formats to get the key to pass to the cache helper. It also makes passing the data access method easier because you don't have to pass the ID into the wrapper method... the whole thing becomes very terse and consistant for the majority of use cases.




Copyright © 2011 Dowemo All rights reserved.    Creative Commons   AboutUs