對一些瀏覽頻次多、數據量大的數據,使用緩存會比較好,而對一些瀏覽頻次低,或內容因用戶不同的,不太適合使用緩存。
在控制器層面,MVC為我們提供了OutputCacheAttribute特性;在數據層使用緩存,用System.Runtime.Caching是不錯的選擇。
控制器層面使用OutputCacheAttribute緩存
□ OutputCacheAttribute默認的緩存時間是60秒。
[OutputCache(Duration=20, VaryByParam="none")]
public ActionResult Index()
{
ViewBag.Message = DateTime.Now.ToString();
return View();
}
□ 設置緩存位置
緩存的位置通過OutputCacheLocation這個枚舉來設置,默認的緩存位置是OutputCacheLocation.Any。OutputCacheLocation其它枚舉項包括:Client,Downstream, Server, None, or ServerAndClient。如果我們想把一個與用戶有關的信息保存在客戶端:
[OutputCache(Duration = 7200, Location = OutputCacheLocation.Client, VaryByParam = "none", NoStore = true)]
public ActionResult Index()
{
ViewBag.Message = "Welcome : " + User.Identity.Name;
return View();
}
數據層緩存,通過System.Runtime.Caching
□ 創建一個叫Demo的數據庫,並創建表Vehicle。
□ 從數據庫生成一個"ADO.NET實體數據模型"CachingDemo.edmx
同時,自動生成了繼承EF的DbContext的類DemoEntities:
並且,在配置文件中自動生成了EF相關內容和連接字符串:
□ 引入System.Runtime.Cache
□ 緩存接口
namespace MvcApplication1.Cache
{
public interface ICacheProvider
{
object Get(string key);
void Set(string key, object data, int cacheTime);
bool IsSet(string key);
void Invalidate(string key);
}
}
□ 緩存實現
using System;
using System.Runtime.Caching;
namespace MvcApplication1.Cache
{
public class DefaultCacheProvider : ICacheProvider
{
private ObjectCache Cache
{
get { return MemoryCache.Default; }
}
public object Get(string key)
{
return Cache[key];
}
public void Set(string key, object data, int cacheTime)
{
CacheItemPolicy policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime);
Cache.Add(new CacheItem(key, data), policy);
}
public bool IsSet(string key)
{
return (Cache[key] != null);
}
public void Invalidate(string key)
{
Cache.Remove(key);
}
}
}
□ Vehicle的Repository接口:
using System.Collections.Generic;
using MvcApplication1.Models;
namespace MvcApplication1.Repository
{
public interface IVehicleRepository
{
void ClearCache();
IEnumerable<Vehicle> GetVehicles();
}
}
□ Vehicle的Repository接口實現:
using System.Collections.Generic;
using System.Linq;
using MvcApplication1.Cache;
using MvcApplication1.Models;
namespace MvcApplication1.Repository
{
public class VehicleRepository : IVehicleRepository
{
protected DemoEntities DataContext { get; private set; }
public ICacheProvider Cache { get; set; }
public VehicleRepository() : this(new DefaultCacheProvider())
{
}
public VehicleRepository(ICacheProvider cacheProvider)
{
this.DataContext = new DemoEntities();
this.Cache = cacheProvider;
}
public void ClearCache()
{
Cache.Invalidate("vehicles");
}
public System.Collections.Generic.IEnumerable<Models.Vehicle> GetVehicles()
{
IEnumerable<Vehicle> vehicles = Cache.Get("vehicles") as IEnumerable<Vehicle>;
if (vehicles == null)
{
vehicles = DataContext.Vehicle.OrderBy(v => v.Id).ToList();
if (vehicles.Any())
{
Cache.Set("vehicles",vehicles,30); //設置緩存的時間為30分鍾
}
}
return vehicles;
}
}
}
□ HomeController
using System.Web.Mvc;
using MvcApplication1.Repository;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public IVehicleRepository Repository { get; set; }
public HomeController(IVehicleRepository repository)
{
this.Repository = repository;
}
public HomeController() : this(new VehicleRepository())
{
}
public ActionResult Index()
{
return View(Repository.GetVehicles());
}
[HttpPost]
public ActionResult Index(FormCollection form)
{
Repository.ClearCache();
return RedirectToAction("Index");
}
}
}
□ Home/Index.cshtml
@model IEnumerable<MvcApplication1.Models.Vehicle>
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<style type="text/css">
table td {
border-collapse: collapse;
border: solid 1px black;
}
</style>
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<th>編號</th>
<th>車型</th>
<th>價格</th>
</tr>
@foreach (var vehicle in Model)
{
<tr>
<td>@vehicle.Id.ToString()</td>
<td>@vehicle.Name</td>
<td>@string.Format("{0:c}",vehicle.Price)</td>
</tr>
}
</table>
@using (Html.BeginForm())
{
<input type="submit" value="使緩存失效重新獲取數據庫數據" id="InvalidButton" name="InvalidButton"/>
}
□ 結果
總結
當在數據層使用System.Runtime.Caching,實際上,所有的緩存操作都圍繞MemoryCache.Default返回類型為ObjectCache緩存而進行。
□ 參考資料
※ Understanding Caching in Asp.Net MVC with example
※ DATA CACHING WITH .NET 4.0 AND ASP.NET MVC – PART 1