我需要使用 System.Web.Caching.Cache 缓存一些数据。不确定它是否重要,但数据不是来自数据库,而是来自过多的自定义对象。
ASP.NET MVC对我来说是一个新手,我想知道这个缓存发生在哪里是有意义的?
在某种程度上,在模型级别缓存是有意义的,但我不一定知道这样做的含义(如果有的话)。如果要在控制器级别进行缓存,是否会影响所有请求,还是只影响当前的 HttpContext ?
那么......应该在何处完成应用程序数据缓存,以及实际执行此操作的好方法是什么?
感谢您的答案!我仍然试图收集在给定不同场景的情况下缓存最有意义的地方。如果一个人正在缓存整个页面,那么将它保留在视图中是有道理的,但是当它不是整个页面时在哪里画线?
答案 0 :(得分:7)
我认为它最终取决于你正在缓存的 。如果要缓存渲染页面的结果,那么它与请求的Http特性紧密相关,并建议使用ActionFilter级别的缓存机制。
另一方面,如果要缓存驱动页面本身的数据,则应考虑模型级缓存。在这种情况下,控制器不关心何时生成数据,它只是对数据执行逻辑操作并准备查看。模型级缓存的另一个参数是,如果您对不附加到Http上下文的模型数据有其他依赖性。
例如,我有一个网络应用程序,我的大多数模型被抽象成一个完全不同的项目。这是因为会有第二个使用相同支持的网络应用程序,并且我们有可能使用相同数据的非基于Web的应用程序。我的大部分数据来自网络服务,这可能是性能杀手,所以我有模型级缓存,控制器和视图完全不知道。
答案 1 :(得分:3)
我不知道你问题的答案,但是Jeff Atwood谈到了SO团队如何使用最新的hanselminutes节目使用stackoverflow.com的MVC框架进行缓存,这可能对你有所帮助:
答案 2 :(得分:3)
我将从 CONTROLLER 缓存开始,使用OutputCache属性,然后根据需要添加模型缓存。它实施起来更快,并且具有即时结果。
这是一个例子。
[OutputCache(Duration=60, VaryByParam="None")]
public ActionResult CacheDemo() {
return View();
}
这意味着如果用户访问该站点(针对属性中定义的缓存要求),则完成工作的工作量会减少。如果只有模型缓存,那么即使逻辑(并且很可能是数据库命中)被缓存,Web服务器仍然必须呈现页面。为什么渲染结果总是一样?
首先从OutputCach
开始,然后在对网站进行性能测试时转移到模型缓存。
输出缓存开始时也简单得多。您不必担心Web场分布式缓存probs(如果您是服务器场的一部分)和模型的缓存提供程序。
您还可以申请甜甜圈缓存 - >仅缓存UI页面的一部分:) Check it out!
答案 3 :(得分:2)
我会选择模型级别的缓存。 (一般来说,建议似乎是在控制器级别最小化业务逻辑 并尽可能多地移动到模型类中。)
这样做怎么样:
我在类Entry
所代表的模型中有一些条目
和条目来源(来自数据库,或'过多的自定义对象')。
在模型中,我创建了一个用于检索条目的界面:
public interface IEntryHandler { IEnumerable<Entry> GetEntries(); }
在模型中我有IEntryHandler
的实际实现
条目从缓存中读取并写入缓存。
public class EntryHandler : IEntryHandler { public IEnumerable<Entry> GetEntries() { // Check if the objects are in the cache: List<Entry> entries = [Get entries from cache] if (entries == null) { // There were no entries in the cache, so we read them from the source: entries = [Get entries from database or 'plethora of custom objects'] [Save the retrieved entries to cache for later use] } return entries; } }
然后控制器会调用IEntryHandler
:
public class HomeController : Controller { private IEntryHandler _entryHandler; // The default constructor, using cache and database/custom objects public HomeController() : this(new EntryHandler()) { } // This constructor allows us to unit test the controller // by writing a test class that implements IEntryHandler // but does not affect cache or entries in the database/custom objects public HomeController(IEntryHandler entryHandler) { _entryHandler = entryHandler; } // This controller action returns a list of entries to the view: public ActionResult Index() { return View(_entryHandler.GetEntries()); } }
这样就可以在不触及真正的缓存/数据库/自定义对象的情况下对控制器进行单元测试。
答案 4 :(得分:1)
我认为缓存应该以某种方式与模型相关。我认为控制器不应该更关心数据。控制器的职责是将数据 - 无论它来自何处 - 映射到视图。
还要考虑为什么需要缓存?你想保存处理,数据传输还是什么?这将帮助您了解获取缓存层所需的具体位置。
答案 5 :(得分:1)
这完全取决于操作的成本。如果您有复杂的查询,那么在控制器级别缓存数据可能是有意义的,这样查询就不会再次执行(直到缓存过期)。
请记住,缓存是一个非常复杂的主题。您可以在缓存中存储许多不同的地方: