问题 在ASP.NET MVC 3中缓存数据


我有一个ASP.NET MVC 3应用程序,基本上只是一组Web服务。这些Web服务由一组Controller操作公开。每个控制器操作都会查询我的数因为我的数据很少改变,并且陈旧的数据不是一个问题,我想我会实现一些缓存来提高性能。我的目标是:

  1. 永远不要缓存对用户的响应。
  2. 将数据库记录缓存最多24小时。如果已经过了24小时,请再次点击数据库。

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

HttpContext.Response.Cache.SetCacheability(cacheability)

但是,我不知道如何在内存中缓存我的数据库记录长达24小时。有没有人对如何做到这一点有任何建议?我甚至不确定在哪里看。

谢谢


12051
2018-06-14 13:15


起源

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


答案:


你可以使用 System.Runtime.Caching 命名空间(或ASP.NET缓存,但这是较旧的,只能在Web应用程序中使用)。

这是一个示例函数,您可以使用它来包装当前的数据检索机制。您可以更改MemoryCache.Add中的参数来控制缓存的数量,但是您要求24h以上。

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缓存依赖项。如果它非常静态,那么这将按照你的要求进行。


8
2018-06-14 14:51



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


MVC框架是持久性不可知的。没有内置的方法来存储数据,因此没有内置的方法来缓存存储的数据。

OutputCache 属性可用于缓存服务器响应。但是你明确表示那不是你想做的事情。

但是,您仍然可以使用内置功能 OutputCache 如果你想留在MVC框架内。考虑将要缓存的数据公开为JSON结果

[OutputCache(Duration = 86400)]
public JsonResult GetMyData() {
    var results = QueryResults();
    return Json(results);
}

JSON字符串在 /ControllerName/GetMyData 将被缓存24小时,因此实际查询每天只会运行一次。这意味着您必须在最终页面上实现AJAX调用,或者从服务器进行另一次HTTP调用。这些都不是理想的。

我会在MVC框架之外寻找另一个解决问题的方法。考虑 memcached的,就是为了这个目的而创建的。


2
2018-06-14 13:49





你所说的并不完全是MVC的责任。 ASP.Net只允许你生成它所产生的东西(而且这是他们的回应,而且很明显)。

如果要缓存数据,最好将其与生成它的位置相同 - 在BL或数据层中的某个位置。

你可以这样做:

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 在这里显示您的实际数据。添加此类后,替换您的 GetData() 方法 DataCacher.Data

希望它有助于或至少引导您进一步思考。


2
2018-06-14 14:44





如果您正在使用MSSQL,您可能需要查看 SQL缓存依赖项

我不确定您是否可以将缓存过期配置为24小时,但是您可能不需要缓存依赖性 - 只要数据库有更新,它就会使缓存失效(即应该比到期时更有效)战略)。


1
2018-06-14 13:58





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


0
2018-06-14 13:23