在ASP.NET MVC 3中缓存数据

12

我有一个ASP.NET MVC 3应用程序,基本上只是一组Web服务。这些Web服务由一组控制器操作公开。每个控制器操作查询我的数据库。因为我的数据很少更改,并且不关心过期的数据,所以我想实现一些缓存以提高性能。我的目标是:

  1. 永远不要将响应缓存到用户。
  2. 缓存数据库记录长达24小时。如果24小时已过,则再次访问数据库。

这样做有意义吗?我知道如何防止响应被缓存。我只需使用以下内容:

HttpContext.Response.Cache.SetCacheability(cacheability)

然而,我不确定如何将我的数据库记录在内存中缓存长达 24 小时。有人有任何关于如何做到这一点的建议吗?我甚至不知道该去哪里看。

谢谢


你是想将整个表的内容简单地缓存到内存中,还是想使用LRU缓存来缓存部分内容? - hatchet - done with SOverflow
1
看起来你并不是在寻找MVC框架提供的解决方案。MVC框架旨在为用户创建响应,并可以使用内置的OutputCache属性缓存这些响应。由于您不希望响应被缓存,因此您可能需要寻找一种更抽象的查询结果缓存方法,而不是与MVC框架绑定的方法(如memcached等)。 - ken
我想将一个表的所有内容缓存到内存中。实际上,在我的实例中,我的表已经被转换为CLR对象。因此,理想情况下,我只想缓存这些对象。 - user70192
@user70192 -- 对的。我认为MVC不是完成那项任务的正确工具。请看我的回答。 - ken
5个回答

8
你可以使用 System.Runtime.Caching 命名空间 (或 ASP.NET 缓存,但这是旧的且只能在 Web 应用程序中使用)。下面是一个示例函数,你可以将其用于包装当前的数据检索机制。您可以更改 MemoryCache.Add 中的参数以控制缓存量,但上面请求了 24 小时。
using System.Runtime.Caching;    // At top of file

public IEnumerable<MyDataObject> GetData() 
{
    IEnumerable<MyDataObject> data = MemoryCache.Default.Get(MYCACHEKEY) as IEnumerable<MyDataObject>;
    if (data == null)
    {
        data = // actually get your data from the database here
        MemoryCache.Default.Add(MYCACHEKEY, data, DateTimeOffset.Now.AddHours(24));
    }
    return data;
}

如@Bond所提到的,如果你缓存的数据可能在24小时内更改,你也可以考虑使用SQL缓存依赖项。但如果数据相对静态,这个方法就可以实现你的要求。


大部分时间我都在用 .NET 3.5,我还没有听说过这个。看起来不错——有点像开箱即用的 memcached。它可以跨多台机器分布吗? - ken
它不是跨多台机器的,它只是一个内存解决方案。它与ASP.NET高速缓存 (System.Web.Caching) 完全相同,但也可用于非ASP.NET应用程序。 - Richard

2
MVC框架与持久性无关,没有内置的存储数据的方法,因此也没有内置的缓存存储数据的方法。可以使用“OutputCache”属性来缓存服务器响应,但您明确表示这不是您想要做的事情。但是,如果您想保留MVC框架中的操作,则仍然可以使用内置的“OutputCache”。考虑将要缓存的数据公开为JSON结果。
[OutputCache(Duration = 86400)]
public JsonResult GetMyData() {
    var results = QueryResults();
    return Json(results);
}

/ControllerName/GetMyData处的JSON字符串将被缓存24小时,因此实际查询每天只会运行一次。这意味着您需要在最终页面上实现AJAX调用或从服务器发起另一个HTTP调用。但这两种方法都不是理想的。

我建议您在MVC框架之外寻找其他解决方案。考虑使用memcached,它正是为此目的而创建的。


2
你所说的并不完全是MVC的职责。ASP.Net只允许你缓存它生成的内容(显然这些是响应内容)。
如果你想要缓存数据,最好在业务逻辑层或数据层中缓存数据,就像它产生的地方一样。
你可以这样做:
public class DataCacher
{
    private static String data;
    private static DateTime updateTime;

    private DataCacher() { }

    public static String Data
    {
        get
        {
            if (data == null || updateTime > DateTime.Now)
            {
                data = "Insert method that requests your data form DB here: GetData()";
                updateTime = DateTime.Now.AddDays(1);
            }
            return data;
        }
    }
}

String data 表示您的实际数据。添加此类后,请使用 DataCacher.Data 替换您的 GetData() 方法。

希望这有所帮助,或者至少引导您进一步思考。


1
如果您正在使用MSSQL,您可能需要查看SQL Cache Dependency
我不确定您是否可以将缓存过期配置为24小时,但是通过使用缓存依赖项,您可能不需要这样做 - 它将在数据库更新时使缓存无效(即应该比时间过期策略更有效)。

0

这里有一篇很好的文章,讨论了几种与 ASP.NET MVC 3 相关的性能实践,其中提到了缓存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接