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

□ 思路

1、缓存是以键值<string, object="">寄存的,在创立缓存的时分,先把IDictionary<int,t>作为缓存内容存储,int为T的主键。

2、EF上下文保留的时分时分把改变保留到数据库,并更新缓存中的内容。

● 先找出上下文中状况为added或modified的实体:var changeobjects
● 把改变保留数据到数据库:context.SaveChanges()
● 依据缓存key获取类型为IDictionary<int,t>的缓存内容:var cacheData = Cache.Get("vehicles") as Dictionary<int, vehicle="">;
● 最终遍历这些改变的实体,更新缓存项:cacheData[vehicle.Id] = vehicle;

□ 缓存接口

    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.Runtime.Caching的MemoryCache.Default回来类型为ObjectCache的缓存特点完成缓存接口:获取缓存项、设置缓存、判别是不是设置缓存、清空缓存。

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

□ Model

    public partial class Vehicle
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
    }

□ 对于Vehicle的Repositoy接口:

using System.Collections.Generic;
using MvcApplication1.Models;
 
namespace MvcApplication1.Repository
{
    public interface IVehicleRepository
    {
        void ClearCache();
        IEnumerableGetVehicles();
        void Insert(Vehicle vehicle); 
        void Update(Vehicle vehicle);
        void SaveChanges();
    }
}
 

□ 对于Vehicle的Repositoy接口完成:

using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Infrastructure;
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 GetVehicles()
        {
            var vehicles = Cache.Get("vehicles") as IDictionary<int, Vehicle>;
            if (vehicles == null)
            {
                vehicles = DataContext.Vehicle.ToDictionary(v => v.Id);
                if (vehicles.Any())
                {
                    Cache.Set("vehicles",vehicles,30);
                }
            }
            return vehicles.Values;
        }
 
        public void Update(Vehicle vehicle)
        {
            if (vehicle != null)
            {
                DataContext.Set().Attach(vehicle);
                DataContext.Entry(vehicle).State = EntityState.Modified;
            }
        }
 
        public void Insert(Vehicle vehicle)
        {
            DataContext.Set().Add(vehicle);
        }
 
        public void SaveChanges()
        {
            //获取上下文中EntityState状况为added或modified的Vehicle
             var changeobjects = DataContext.ChangeTracker.Entries();
 
            //把改变保留到数据库
            DataContext.SaveChanges();
 
            //更新缓存中有关的Vehicle
            var cacheData = Cache.Get("vehicles") as Dictionary<int, Vehicle>;
            if (cacheData != null)
            {
                foreach (var item in changeobjects)
                {
                    var vehicle = item.Entity as Vehicle;
                    cacheData[vehicle.Id] = vehicle;
                }
            }
        }
    }
}
 

在保留缓存Cache.Set("vehicles",vehicles,30)之前,把从上下文获取到的数据转换成IDictionary<int,t>类型vehicles = DataContext.Vehicle.ToDictionary(v => v.Id);

□ HomeController

using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication1.Models;
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");
        }
 
        public ActionResult Edit(int id)
        {
            var vehicle = Repository.GetVehicles().Single(v => v.Id == id);
            return View(vehicle);
        }
 
        [HttpPost]
        public ActionResult Edit(Vehicle vehicle)
        {
            Repository.Update(vehicle);
            Repository.SaveChanges();
            return RedirectToAction("Index");
        }
 
        public ActionResult Create()
        {
            return View(new Vehicle());
        }
 
        [HttpPost]
        public ActionResult Create(Vehicle vehicle)
        {
            Repository.Insert(vehicle);
            Repository.SaveChanges();
            return RedirectToAction("Index");
        }
    }
}
 

□ Home/Index.cshtml

@model IEnumerable
 
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 

 
"0" cellspacing="0" border="0">
    
        
        
        
        
    
    @foreach (var vehicle in Model)
    {
        
            
            
            
            
        
    }

编号 车型 报价  
@vehicle.Id.ToString() @vehicle.Name @string.Format("{0:c}",vehicle.Price)
            @Html.ActionLink("修改", "Edit", new { id=vehicle.Id }) 
        
 
@using (Html.BeginForm())
{
    "submit" value="使缓存失效从头获取数据库数据" id="InvalidButton" name="InvalidButton"/>
}
 

    @Html.ActionLink("创立", "Create")

 

□ Home/Create.cshtml


@model MvcApplication1.Models.Vehicle @{ ViewBag.Title = "Create"; Layout = "~/Views/Shared/_Layout.cshtml"; }

Create

@using (Html.BeginForm()) {     @Html.ValidationSummary(true)Vehicle

class="editor-label"> @Html.LabelFor(model => model.Name)
class="editor-field"> @Html.EditorFor(model => model.Name) @Html.ValidationMessageFor(model => model.Name)

class="editor-label"> @Html.LabelFor(model => model.Price)

class="editor-field"> @Html.EditorFor(model => model.Price) @Html.ValidationMessageFor(model => model.Price)

value="Create" />

} @section Scripts { @Scripts.Render("~/bundles/jqueryval") }

□ Home/Edit.cshtml


@model MvcApplication1.Models.Vehicle @{ ViewBag.Title = "Edit"; Layout = "~/Views/Shared/_Layout.cshtml"; }

Edit

@using (Html.BeginForm()) { @Html.ValidationSummary(true)Vehicle@Html.HiddenFor(model => model.Id)

class="editor-label"> @Html.LabelFor(model => model.Name)
class="editor-field"> @Html.EditorFor(model => model.Name) @Html.ValidationMessageFor(model => model.Name)

class="editor-label"> @Html.LabelFor(model => model.Price)

class="editor-field"> @Html.EditorFor(model => model.Price) @Html.ValidationMessageFor(model => model.Price)

value="Save" />

} @section Scripts { @Scripts.Render("~/bundles/jqueryval") }

□ 成果:

创立或修改之前: 

修改更新: 

创立: 

修改创立成功后: 

 

MVC缓存,使用数据层缓存,添加或修改时让缓存失效的更多相关文章

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

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

  2. MVC缓存01,使用控制器缓存或数据层缓存

    对一些浏览频次多.数据量大的数据,使用缓存会比较好,而对一些浏览频次低,或内容因用户不同的,不太适合使用缓存.   在控制器层面,MVC为我们提供了OutputCacheAttribute特性:在数据 ...

  3. XML中 添加或修改时 xmlns="" 怎么删除

    //创建节点时 记得加上  ---> xmldoc.DocumentElement.NamespaceURI XmlElement url = xmldoc.CreateElement(&quo ...

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

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

  5. [开源]OSharpNS 步步为营系列 - 2. 添加业务数据层

    什么是OSharp OSharpNS全称OSharp Framework with .NetStandard2.0,是一个基于.NetStandard2.0开发的一个.NetCore快速开发框架.这个 ...

  6. Caffe实现多标签输入,添加数据层(data layer)

    因为之前遇到了sequence learning问题(CRNN),里面涉及到一张图对应多个标签.Caffe源码本身是不支持多类标签数据的输入的. 如果之前习惯调用脚本create_imagenet.s ...

  7. 程序与CPU,内核,寄存器,缓存,RAM,ROM、总线、Cache line缓存行的作用和他们之间的联系?

    目录 缓存 什么是缓存 L1.L2.L3 为什么要设置那么多缓存.缓存在cup内还是cup外 MESI协议----主流的处理缓存和主存数据不一样问题 Cache line是什么已经 对编程中数组的影响 ...

  8. 给AFNetworking添加请求缓存功能实现在没有网络的情况下返回缓存数据

    原理:先给NSURLSession地Configuration设置一个内存和本地代理,原来的网络请求结束后会查找缓存的代理字典,并执行代理对象对应的操作方法,需要做的就是拦截错误的方法,返回缓存的数据 ...

  9. SpringBoot整合Redis、mybatis实战,封装RedisUtils工具类,redis缓存mybatis数据 附源码

    创建SpringBoot项目 在线创建方式 网址:https://start.spring.io/ 然后创建Controller.Mapper.Service包 SpringBoot整合Redis 引 ...

随机推荐

  1. C语言清空输入缓冲区的N种方法对比

    转自C语言清空输入缓冲区的N种方法对比 C语言中有几个基本输入函数: //获取字符系列 int fgetc(FILE *stream); int getc(FILE *stream); int get ...

  2. 配置PhpStorm调试PHP

    配置PhpStorm调试PHP 第一步:配置 XDebug 下载安装XDebug到本地环境(参考:Zend Studio 9.x + xampp + XDebug 调试环境安装详解),打开php.in ...

  3. java WebService简单使用案例

    首先,建立一个WebService: package garfield; import javax.jws.WebService; import javax.xml.ws.Endpoint; @Web ...

  4. android 双向滑动 seekbar

    实现原理: 1.自定义View,在onDraw(Canvas canvas)中,画出2个Drawable滑动块,2个Drawable滑动条,2个Paint(text) 2.监听onTouchEvent ...

  5. 你们都是怎么阅读android系统源码的,用什么工具?

    如果是eclipse,可以建立java或者c++工程,把framework源码导入.packages目录下的可以建立android工程.sourceinsight的话,建立工程把相应模块的代码添加进去 ...

  6. Learning WCF Chapter1 Generating a Service and Client Proxy

    In the previous lab,you created a service and client from scratch without leveraging the tools avail ...

  7. Learning WCF Chapter2 Data Contracts

    A data contract describes how CLR types map to XSD schema definitions. Data contracts are the prefer ...

  8. 转载--Linux命令top动态观察程序的变化

    转载:http://www.cnblogs.com/allen8807/archive/2010/11/10/1874001.html top:动态观察程序的变化 [root@linux ~]# to ...

  9. Jquery UI dialog 详解 (中文)

    转载▼ 1 属性 1.11 autoOpen ,这个属性为true的时候dialog被调用的时候自动打开dialog窗口.当属性为false的时候,一开始隐藏窗口,知道.dialog("op ...

  10. 传输层之TCP

    ---恢复内容开始--- 坞无尘水槛清,相思迢递隔重城. 秋阴不散霜飞晚,留得枯荷听雨声.    --李商隐 上一篇中我们了解了socket编程是基于TCP或者UDP,所以我们有必要对TCP,和UDP ...