对一些浏览频次多、数据量大的数据,使用缓存会比较好,而对一些浏览频次低,或内容因用户不同的,不太适合使用缓存。

 

在控制器层面,MVC为我们提供了OutputCacheAttribute特性;在数据层使用缓存,用System.Runtime.Caching是不错的选择。

 

  控制器层面使用OutputCacheAttribute缓存

□ OutputCacheAttribute默认的缓存时间是60秒。

[OutputCache(Duration=20, VaryByParam="none")]
public ActionResult Index()
{
 ViewBag.Message = DateTime.Now.ToString();
 return View();
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

□ 设置缓存位置

缓存的位置通过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();
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

  数据层缓存,通过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);
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

□ 缓存实现

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);
        }
    }
}
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

□ Vehicle的Repository接口:

using System.Collections.Generic;
using MvcApplication1.Models;
 
namespace MvcApplication1.Repository
{
    public interface IVehicleRepository
    {
        void ClearCache();
        IEnumerable<Vehicle> GetVehicles();
    }
}
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

□ 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;
        }
    }
}
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

□ 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");
        }
    }
}
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

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

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

□ 结果

页面第一次加载:

在数据库改变数据,页面内容不变:

点击按钮使缓存失效,视图显示数据库最新数据:

 

  总结

当在数据层使用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

MVC缓存01,使用控制器缓存或数据层缓存的更多相关文章

  1. [NewLife.XCode]数据层缓存(网站性能翻10倍)

    NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和 ...

  2. MVC缓存02,使用数据层缓存,添加或修改时让缓存失效

    在"MVC缓存01,使用控制器缓存或数据层缓存"中,在数据层中可以设置缓存的有效时间.但这个还不够"智能",常常希望在编辑或创建的时候使缓存失效,加载新的数据. ...

  3. MVC缓存,使用数据层缓存,添加或修改时让缓存失效

    在"MVC缓存01,运用控制器缓存或数据层缓存"中,在数据层中可以设置缓存的有用时刻.但这个还不够"智能",常常期望在修改或创立的时分使缓存失效,加载新的数据. ...

  4. 老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化

    引言 今天周末,我在家坐着掐指一算,马上又要到一年一度的金九银十招聘季了,国内今年上半年受到 YQ 冲击,金三银四泡汤了,这就直接导致很多今年毕业的同学会和明年毕业的同学一起参加今年下半年的秋招,这个 ...

  5. ECMall关于数据查询缓存的问题

    刚接触Ecmall的二次开发不久,接到一个任务.很常见的任务,主要是对数据库进行一些操作,其中查询的方法我写成这样: 01 function get_order_data($goods_id) 02 ...

  6. MVC学习系列3--怎么从控制器向视图传递数据

    在MVC中,从控制器到视图,传递数据,可以使用 ViewData 和 ViewBag:同样从视图到控制器,传递数据,可以使用Post,QueryString,或者隐藏域:最后从控制器到控制器,传递数据 ...

  7. spring + redis 实现数据的缓存

    1.实现目标 通过redis缓存数据.(目的不是加快查询的速度,而是减少数据库的负担) 2.所需jar包 注意:jdies和commons-pool两个jar的版本是有对应关系的,注意引入jar包是要 ...

  8. .NET MVC控制器向视图传递数据的四种方式

    .NET MVC控制器向视图传递数据的四种方式: 1.ViewBag  ViewBag.Mvc="mvc"; 2.ViewData ViewBag["Mvc"] ...

  9. Catalyst揭秘 Day8 Final 外部数据源和缓存系统

    Catalyst揭秘 Day8 Final 外部数据源和缓存系统 今天是Catalyst部分的收官,主要讲一些杂项内容. 外部数据源处理 什么叫外部数据源,是SparkSql自己支持的一些文件格式,以 ...

随机推荐

  1. 架设 OpenLDAP服务器

    OpenLDAP是一个开放源代码的软件,可以免费获取使用,其主页地址是:http://www.openldap.org/.在RHEL 6上安装OpenLDAP还需要libtool-ltdl-2.2.6 ...

  2. Unity 手指上下左右滑动的判定

    using UnityEngine; using System.Collections; public class jarodInputController : MonoBehaviour { pri ...

  3. 单链表的类的c++实现

    #include<iostream> using namespace std;template <class T>struct linkNode{ T data; linkNo ...

  4. Android 创建内容提供器(ContentResolver)

    如果想实现跨程序共享数据的功能,官方推荐的方式就是使用内容提供器,可以通过新建一个类去继承 ContentResolver 的方式来创建一个自己的内容提供器. ContentProvider 类中有六 ...

  5. Delphi结构体的扩展,可以自动初始化,反初始化,自定义拷贝函数.

    转载:http://www.raysoftware.cn/?p=518&utm_source=tuicool 恭贺Delphi XE7诞生,Delphi XE7在编译器内部集成了我之前所实现的 ...

  6. exit()和_exit()

    进程就好比人一样有其生命,我们通过fork()函数来创建一个进程,那么我们又是如何来中止进程呢. 进程退出 1.在Linux中任何让一个进程退出 进程退出表示进程即将结束.在Linux中进程退出分为了 ...

  7. Python类的特点 (3) :静态方法与类方法

    Python中的方法有4种: 1)模块中的全局方法,不属于任何类,用"模块名.方法名"形式调用. 2)类中定义的实例方法,也被称为绑定方法(Bound method),这种方法的第 ...

  8. Access an instance through a console

    VNC or SPICE is used to view the console output of an instance, regardless of whether or not the con ...

  9. Oracle11g +Win 64+PLSQL9.0

    最近在Oracle11g配置数据库的时候发现了一个问题,就是找不到监听,网上说win7的64位的系统必须装上32位的客户端才能被PLSQL 识别,事实上也是这样,PLSQL 只能识别32位的客户端,所 ...

  10. ios oc 和 swfit 用dispatch_once 创建单例

    网上已经有方法了,我这里就是抄了下,原文链接 http://bj007.blog.51cto.com/1701577/649413 http://blog.csdn.net/u010124617/ar ...