MVC緩存01,使用控制器緩存或數據層緩存


對一些瀏覽頻次多、數據量大的數據,使用緩存會比較好,而對一些瀏覽頻次低,或內容因用戶不同的,不太適合使用緩存。

 

在控制器層面,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。

5

 

□ 從數據庫生成一個"ADO.NET實體數據模型"CachingDemo.edmx

6

同時,自動生成了繼承EF的DbContext的類DemoEntities:

7

 

並且,在配置文件中自動生成了EF相關內容和連接字符串:

8

□ 引入System.Runtime.Cache

9

 

□ 緩存接口

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"/>
}
 


□ 結果

頁面第一次加載:
1

在數據庫改變數據,頁面內容不變:
2

點擊按鈕使緩存失效,視圖顯示數據庫最新數據:
3

 

  總結

當在數據層使用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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM