如何将数据库数据缓存到内存中以供MVC应用程序使用?

时间:2013-06-25 19:10:46

标签: c# caching asp.net-mvc-4

我有一个有点复杂的权限系统,总共使用六个数据库表,为了加快速度,我想将这些表缓存在内存中,而不是每次加载页面时都要访问数据库。

但是,我需要在添加新用户或更改权限时更新此缓存。我不确定如何在内存缓存中使用它,以及如何安全地更新它而不会在更新的同时访问时引起问题

有没有人有一个如何做这样的事情的例子,或者能指出我正确的研究方向?

6 个答案:

答案 0 :(得分:2)

在不了解应用程序结构的情况下,有很多可能的选择。其中一个选项可能是抽象存储库接口后面的数据访问,并处理该存储库中的内存缓存。像存储库对象上的私有IEnumerable<T>一样简单。

因此,例如,假设您有一个User对象,其中包含有关用户的信息(名称,权限等)。你有UserRepository一些基本的提取/保存方法。在该存储库中,您可以维护一个私有静态HashSet<User>,其中包含已从数据库中检索的User个对象。

当您从存储库中获取User时,它首先检查HashSet是否有要返回的对象,如果它没有找到它从数据库获取它,则将其添加到HashSet,然后返回它。保存User时,它会同时更新HashSet和数据库。

同样,在不知道代码库和整体设计的细节的情况下,很难给出更具体的答案。但这应该是适用于任何应用程序的通用解决方案。

答案 1 :(得分:1)

我会在您使用它时缓存项目,这意味着在您获取数据时在数据层上检查缓存是否可用,否则您将转到数据库并在之后缓存结果。

public AccessModel GetAccess(string accessCode)
{
     if(cache.Get<string>(accessCode) != null)
          return cache.Get<string>(accessCode);

     return GetFromDatabase(accessCode);
}

然后我会想到我的缓存无效策略。您可以采用以下两种方式:

一个将过期数据设置为1小时,然后您只需在一小时内点击一次数据库。

或者在更新数据时使缓存无效。这肯定是最好的,但有点复杂。

希望它有所帮助。

注意:您可以使用ASP.NET缓存或其他解决方案,例如memcached,具体取决于您的基础架构

答案 2 :(得分:0)

是否每次页面加载都会影响数据库是问题还是加入六个表是问题?

如果只是连接速度很慢,为什么不创建一个数据库表来以更容易和更快速的方式汇总数据?

这样,您每次添加用户或更新权限时都必须更新摘要表。如果将所有这些分组到一个事务中,则不应该出现不同步数据的问题。

答案 3 :(得分:0)

您可以利用ASP.NET缓存和SqlCacheDependency类。有article on MSDN

答案 4 :(得分:0)

您可以使用ASP.Net中内置的Cache对象。这是一个article,解释了如何。

答案 5 :(得分:0)

我可以建议在Application state object中缓存这些数据。为了线程安全使用,请考虑使用lock operator。您的代码看起来像这样:

public void ClearTableCache(string tableName) 
{
    lock (System.Web.HttpContext.Current) 
    {
       System.Web.HttpContext.Current.Application[tableName] = null;
    }        
}

public SomeDataType GetTableData(string tableName) 
{
    lock (System.Web.HttpContext.Current) 
    {
       if (System.Web.HttpContext.Current.Application[tableName] == null) 
       {
          //get data from DB then put it into application state
          System.Web.HttpContext.Current.Application[tableName] = dataFromDb;
          return dataFromDb;
       }
       return (SomeDataType)System.Web.HttpContext.Current.Application[tableName];
    }            
}