当前位置:  开发笔记 > 后端 > 正文

如何在MVC应用程序中缓存数据

如何解决《如何在MVC应用程序中缓存数据》经验,为你挑选了5个好方法。

我在MVC应用程序中阅读了大量有关页面缓存和部分页面缓存的信息.但是,我想知道如何缓存数据.

在我的场景中,我将使用LINQ to Entities(实体框架).在第一次调用GetNames(或任何方法)时,我想从数据库中获取数据.我想将结果保存在缓存中,并在第二次调用时使用缓存版本(如果存在).

任何人都可以展示一个如何工作的例子,应该在哪里实现(模型?)以及它是否可行.

我已经在传统的ASP.NET应用程序中看到了这一点,通常用于非常静态的数据.



1> Hrvoje Hudo..:

这是我使用的一个很好的简单缓存助手类/服务:

using System.Runtime.Caching;  

public class InMemoryCache: ICacheService
{
    public T GetOrSet(string cacheKey, Func getItemCallback) where T : class
    {
        T item = MemoryCache.Default.Get(cacheKey) as T;
        if (item == null)
        {
            item = getItemCallback();
            MemoryCache.Default.Add(cacheKey, item, DateTime.Now.AddMinutes(10));
        }
        return item;
    }
}

interface ICacheService
{
    T GetOrSet(string cacheKey, Func getItemCallback) where T : class;
}

用法:

cacheProvider.GetOrSet("cache key", (delegate method if cache is empty));

缓存提供程序将检查缓存中是否存在名称为"cache id"的内容,如果没有,它将调用委托方法来获取数据并将其存储在缓存中.

例:

var products=cacheService.GetOrSet("catalog.products", ()=>productRepository.GetAll())


这个类不应该依赖于HttpContext.我在这里简化它只是为了举例.必须通过构造函数插入缓存对象 - 然后可以将其替换为其他缓存机制.所有这些都是通过IoC/DI以及静态(单例)生命周期实现的.
这是一个很棒的低级解决方案.像其他人所提到的那样,你想要将它包装在类型安全的,特定于域的类中.由于神奇的字符串,直接在控制器中访问它将是一个维护噩梦.
我已经对此进行了调整,以便通过使用HttpContext.Current.Session来为每个用户会话使用缓存机制.我还在我的BaseController类上放置了一个Cache属性,以便轻松访问并更新构造函数,允许DI进行单元测试.希望这可以帮助.
@Brendan - 更糟糕的是,它为缓存键设置了魔术字符串,而不是从方法名称和参数中推断它们.

2> terjetyl..:

在模型中引用System.Web dll并使用System.Web.Caching.Cache

    public string[] GetNames()
    {
      string[] names = Cache["names"] as string[];
      if(names == null) //not in cache
      {
        names = DB.GetNames();
        Cache["names"] = names;
      }
      return names;
    }

有点简化,但我想这会奏效.这不是MVC特定的,我一直使用这种方法来缓存数据.


我不推荐这个解决方案:在返回时,你可能会再次获得一个null对象,因为它在缓存中重新读取它可能已经从缓存中删除了.我宁愿这样做:public string [] GetNames(){string [] noms = Cache ["names"]; if(noms == null){noms = DB.GetNames(); 缓存["名称"] = noms; } return(noms); }
如果你没有设置expiration ..默认情况下缓存是否会过期?

3> Oli..:

我指的是TT的帖子,并建议采用以下方法:

在模型中引用System.Web dll并使用System.Web.Caching.Cache

public string[] GetNames()
{ 
    var noms = Cache["names"];
    if(noms == null) 
    {    
        noms = DB.GetNames();
        Cache["names"] = noms; 
    }

    return ((string[])noms);
}

您不应该返回从缓存中重新读取的值,因为您永远不会知道在该特定时刻它是否仍在缓存中.即使你之前在声明中插入它,它可能已经消失或者从未被添加到缓存中 - 你只是不知道.

因此,您添加从数据库读取的数据并直接返回,而不是从缓存中重新读取.


@Baddie是的.但是这个例子与Oli所指的第一个不同,因为他没有再次访问缓存 - 问题是只做:return(string [])Cache ["names"]; .. COULD导致返回null值,因为它已经过期了.这不太可能,但它可能发生.这个例子更好,因为我们将db返回的实际值存储在内存中,缓存该值,然后返回该值,而不是从缓存中重新读取的值.

4> juFo..:

适用于.NET 4.5+框架

添加参考: System.Runtime.Caching

添加使用声明: using System.Runtime.Caching;

public string[] GetNames()
{ 
    var noms = System.Runtime.Caching.MemoryCache.Default["names"];
    if(noms == null) 
    {    
        noms = DB.GetNames();
        System.Runtime.Caching.MemoryCache.Default["names"] = noms; 
    }

    return ((string[])noms);
}

在.NET Framework 3.5和更早版本中,ASP.NET在System.Web.Caching命名空间中提供了内存中缓存实现.在以前版本的.NET Framework中,缓存仅在System.Web命名空间中可用,因此需要依赖ASP.NET类.在.NET Framework 4中,System.Runtime.Caching命名空间包含为Web和非Web应用程序设计的API.

更多信息:

https://msdn.microsoft.com/en-us/library/dd997357(v=vs.110).aspx

https://docs.microsoft.com/en-us/dotnet/framework/performance/caching-in-net-framework-applications



5> Brendan Enri..:

史蒂夫史密斯做了两篇很棒的博客文章,演示了如何在ASP.NET MVC中使用他的CachedRepository模式.它有效地使用存储库模式,允许您在不必更改现有代码的情况下获得缓存.

http://ardalis.com/Introducing-the-CachedRepository-Pattern

http://ardalis.com/building-a-cachedrepository-via-strategy-pattern

在这两篇文章中,他向您展示了如何设置此模式,并解释了它为何有用.通过使用此模式,您可以获得缓存,而无需现有代码查看任何缓存逻辑.实际上,您使用缓存的存储库就像它是任何其他存储库一样.


链接再次起作用.我猜他们现在不死了:)
内容已经移动了.http://ardalis.com/Introducing-the-CachedRepository-Pattern和http://ardalis.com/building-a-cachedrepository-via-strategy-pattern
推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有