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

 

在控制器层面,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. [BZOJ3991][SDOI2015]寻宝游戏

    [BZOJ3991][SDOI2015]寻宝游戏 试题描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择 ...

  2. H5canvas赛车游戏-基于lufylegend引擎

    lufylegend引擎是canvas游戏中,比较简单的引擎之一,它不需要配置环境,类似引入jquery包的方式,引用对应js文件即可 lufylegend官方网站:http://www.lufyle ...

  3. (原创)在service中定时执行网络操作的几点说明

    执行网络操作是耗时操作,即便是在service中也要放到子线程中执行 这里我用到了async-http-client框架来执行异步请求操作 计时用的java原生Timer和TimerTask类 本来这 ...

  4. BZOJ 3364: [Usaco2004 Feb]Distance Queries 距离咨询

    Description 一棵树,询问两点间距离. Sol 倍增. 方向没用. 没有然后了. Code /************************************************ ...

  5. Python检验一个文件是否存在,如果不在就自己填写内容。

    import os while True: filename=input('Please enter the filename') if os.path.exists(filename): print ...

  6. Python统计百分比及排序

    source.txt: 60行 89 91 93 90 92 92 94 92 89 95 93 92 90 92 93 94 94 92 90 92 92 92 ... 统计各个值的百分比,并排序 ...

  7. iOS 中 为UIView添加背景图片

    创建UIImage的方法有两种: UIImage *image = [UIImageimageNamed:@"image.jpg"];//这种不释放内存,要缓存 NSString ...

  8. 对于Tomcat服务器环境变量和启动配置的一点补充

    我们之前第一次使用Tomcat服务器运行jsp应用时,曾经给Tomcat配置过一个环境变量CATALINA_HOME,这个变量指定了Tomcat的安装位置,对于多个开发项目,我们一般会释放多个tomc ...

  9. 3. javacript高级程序设计-基本概念

    1.1 语法 ECMAScript借鉴了C和其他类C语言的语法 1.1.1 区分大小写 ECMAScript中的一切(变量,函数和操作符)都是区分大小写的,变量test和Test是不同的变量 1.1. ...

  10. Tesseract-OCR text2image.exe [ x86 支持 XP ]

    Tesseract-OCR 工具中的 text2image.exe ,下载其他人编译的在 win 系统都无法正常运行. 折腾了好久终于编译出能正常运行的. --font="font name ...