我想在 ASP.NET MVC 中缓存对象。我有BaseController
,我希望所有控制器继承。在 BaseController 中有一个User
属性,它只是从数据库中获取用户数据,这样我就可以在控制器中使用它,或者将它传递给视图。
我想缓存这些信息。我在每个页面上都使用此信息,因此无需每个页面请求转到数据库。
我喜欢这样的东西:
if(_user is null)
GrabFromDatabase
StuffIntoCache
return CachedObject as User
如何在 ASP.NET MVC 中实现简单缓存?
8 回答
您仍然可以使用缓存(在所有响应中共享)和会话(每个用户唯一)进行存储。
我喜欢以下“尝试从 cache/create 和存储”模式(c#-like 伪代码):
你会这样使用它:
您可以将此模式调整为 Session,ViewState(ugh)或任何其他缓存机制。你也可以扩展 ControllerContext.HttpContext(我认为它是 System.Web.Extensions 中的包装器之一),或者创建一个新类来做一些模拟缓存的空间。
我接受了 Will 的回答并对其进行了修改以使
CacheExtensions
类保持静态并建议稍微改动以便处理Func<T>
为null
的可能性:我还要考虑进一步实现一个扩展 System.Web.HttpSessionStateBase 抽象类的可测试的 Session 解决方案。
如果您希望缓存请求的长度,请将其放在控制器基类中:
如果要缓存更长时间,请使用将 ControllerContext 调用替换为 Cache [14]。如果您确实选择使用 Cache 对象进行更长时间的缓存,则需要使用唯一的缓存键,因为它将在 requests/users 之间共享。
我喜欢隐藏数据缓存在存储库中的事实。您可以通过 HttpContext.Current.Cache 属性访问缓存,并使用“User”id.ToString()作为密钥存储用户信息。
这意味着对存储库中的用户数据的所有访问都将使用缓存数据(如果可用),并且不需要在模型,控制器或视图中更改代码。
我已经使用此方法来纠正系统上的严重性能问题,该系统正在查询每个 User 属性的数据库,并将页面加载时间从几分钟减少到单位数秒。
@njappboy:很好的实施。我只会将
Generator( )
调用推迟到最后一个负责任的时刻。因此您也可以缓存方法调用。这里的其他几个答案不涉及以下内容:
缓存踩踏事件
双重检查锁定
这可能导致生成器(可能需要很长时间)在不同的线程中运行多次。
这是我的版本不应该遇到这个问题:
如果您不需要 ASP.NET 缓存的特定失效功能,静态字段非常好,轻量级且易于使用。但是,只要您需要高级功能,就可以切换到 ASP.NET 的
Cache
对象进行存储。我使用的方法是创建属性和
private
字段。如果该字段为null
,则该属性将填充并返回该字段。我还提供了一个InvalidateCache
方法,手动将字段设置为null
。这种方法的优点是缓存机制封装在属性中,如果需要,可以切换到不同的方法。使用最小的缓存锁定实现。存储在缓存中的值包装在容器中。如果该值不在缓存中,则值容器将被锁定。仅在创建容器期间锁定缓存。