10

I have four classes as following:

public class Section
{
    public int SectionId { get; set; }
    public string Name { get; set; }
    public string Title { get; set; }
    public string MetaTag { get; set; }
    public string MetaDescription { get; set; }
    public string UrlSafe { get; set; }
    public string Header { get; set; }
    public string ImageName { get; set; }
}       

public interface ISectionRepository
{
    List<Section> GetAllSections();
}

public class SectionRepository : ISectionRepository
{
    Context context = new Context();

    public List<Section> GetAllSections()
    {
        return context.Sections.ToList();
    }
}

public class SectionApplication
{
    SectionRepository sectionRepo = new SectionRepository();

    public List<Section> GetAllSections()
    {
        return sectionRepo.GetAllSections();
    }
}

And in my controller, I have

public class SectionController : Controller
{
    SectionApplication sectionApp = new SectionApplication();

    public ActionResult Index()
    {
        return View(sectionApp.GetAllSections());
    }
}

Now, I want to do cache sections on memory for a specific time in order to read sections from cache if it exists, else read it from database.

Sae1962
  • 1,122
  • 15
  • 31
Hamid Reza
  • 2,913
  • 9
  • 49
  • 76

3 Answers3

20

Simple possible approach, you can use MemoryCache, the code will look like:

public List<Section> GetAllSections()
{
    var memoryCache = MemoryCache.Default;

    if (!memoryCache.Contains("section"))
    {
        var expiration = DateTimeOffset.UtcNow.AddMinutes(5);
        var sections = context.Sections.ToList();

        memoryCache.Add("section", sections, expiration);
    }

    return memoryCache.Get("section", null);
}
Paul
  • 1,375
  • 2
  • 21
  • 55
cuongle
  • 74,024
  • 28
  • 151
  • 206
  • I have an error: Cannot implicitly convert type 'object' to System.Collections.Generic.List'. An explicit conversion exists (are you missing a cast?) What should I do? – Hamid Reza Feb 26 '13 at 05:34
  • 1
    @HamidReza: You should explicit casting when getting objet out of cache – cuongle Feb 26 '13 at 06:07
  • OW.Yes.I did that.Thank you. – Hamid Reza Feb 26 '13 at 06:21
  • For this example specifically, it looks like [`AddOrGetExisting`](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.caching.objectcache.addorgetexisting?view=netframework-4.8) could also be used instead. – Kevin Jul 17 '19 at 17:44
2

You do the caching by adding a new class with a timeout. When you read the first time, you read directly from the database and write the data into a property of the new class and make a timestamp. In the next read operation, you check your new class to see if the timeout has been reached. If not, you read the data from the new class. Otherwise, you read from the database and put it into the cache class and update the timeout.

ArtOfCode
  • 5,702
  • 5
  • 37
  • 56
Tomtom
  • 9,087
  • 7
  • 52
  • 95
1
public interface IRepositoryCollection
{
    DateTime dateCreated { get; set; }
}

public class Cache<T> : Dictionary<string, T>
{
    private int cacheDuration = 1;
    private int maxCacheSize = 20;

    public Cache(int cacheDuration, int maxCacheSize)
    {
        this.cacheDuration = cacheDuration;
        this.maxCacheSize = maxCacheSize;
    }

    public new void Add(string key, T invoices)
    {
        base.Add(key, invoices);
        RemoveOld();
        RemoveOldest();
    }

    public void RemoveOld()
    {
        foreach (KeyValuePair<string, T> cacheItem in this)
        {
            Interfaces.IRepositoryCollection currentvalue = (Interfaces.IRepositoryCollection)cacheItem.Value;

            if (currentvalue.dateCreated < DateTime.Now.AddHours(-cacheDuration))
            {
                this.Remove(cacheItem.Key);
            }
        }
    }

    public void RemoveOldest()
    {
        do
        {
            this.Remove(this.First().Key);
        }
        while (this.Count > maxCacheSize);
    }
}


public class ProformaInvoiceCache
{
    private static Cache<ProformaInvoices> cache = new Cache<ProformaInvoices>(1, 20);

    public static string AddInvoiceCollection(ProformaInvoices invoices)
    {
        // Adds invoice collection to static instance of cache, returns guid required to retrieve item from cache
        return cache.Add(invoices);
    }

    public static ProformaInvoices GetInvoiceCollection(string guid)
    {
        // Gets invoice collection from cache corresponding to passed guid
        return cache.Get(guid);
    }
}
Jamie Pearcey
  • 345
  • 1
  • 10