c#本地缓存当数据库表更改时,缓存失效。
web.config
<?xml version="1.0" encoding="utf-8"?>
<!--
有关如何配置 ASP.NET 应用程序的详细信息,请访问
http://go.microsoft.com/fwlink/?LinkId=152368
-->
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="TestMvcConnectionString"
connectionString="Data Source=LJJ-FF\LJJ;Initial Catalog=TestMvc;User ID=sa;Password=111111;Max Pool Size=500;Min Pool Size=1;"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="2.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<system.web>
<caching>
<sqlCacheDependency enabled="true" pollTime="">
<databases>
<add connectionStringName="TestMvcConnectionString" name="TestMvc"/>
</databases>
</sqlCacheDependency>
</caching>
<httpRuntime targetFramework="4.5" />
<compilation debug="true" targetFramework="4.5" />
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="" />
</authentication>
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
</namespaces>
</pages>
<profile defaultProvider="DefaultProfileProvider">
<providers>
<add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</profile>
<membership defaultProvider="DefaultMembershipProvider">
<providers>
<add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="" minRequiredPasswordLength="" minRequiredNonalphanumericCharacters="" passwordAttemptWindow="" applicationName="/" />
</providers>
</membership>
<roleManager defaultProvider="DefaultRoleProvider">
<providers>
<add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</roleManager>
<!--
If you are deploying to a cloud environment that has multiple web server instances,
you should change session state mode from "InProc" to "Custom". In addition,
change the connection string named "DefaultConnection" to connect to an instance
of SQL Server (including SQL Azure and SQL Compact) instead of to SQL Server Express.
-->
<sessionState mode="InProc" customProvider="DefaultSessionProvider">
<providers>
<add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
</providers>
</sessionState>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.3.0.0" newVersion="1.3.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
</configuration>
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Caching;
using System.Web.Mvc; namespace TestSystemWebCache.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/ public ActionResult Index()
{
System.Web.Caching.Cache cache = System.Web.HttpContext.Current.Cache; //数据库连接字符串名字
//启用更改通知
SqlCacheDependencyAdmin.EnableNotifications(System.Configuration.ConfigurationManager.ConnectionStrings["TestMvcConnectionString"].ConnectionString);
//数据库连接字符串名字和表的名字
//连接到 SQL Server 数据库并为 SqlCacheDependency 更改通知准备数据库表
SqlCacheDependencyAdmin.EnableTableForNotifications(System.Configuration.ConfigurationManager.ConnectionStrings["TestMvcConnectionString"].ConnectionString, "Student"); //制定缓存策略
SqlCacheDependency scd = new SqlCacheDependency("TestMvc", "Student");//数据库的名字和表名字 string oldwCache = (string)cache.Get("SiteInfo");
ViewBag.oldwCache = oldwCache; if (oldwCache == null)
{ //插入缓存
cache.Insert("SiteInfo", "ljj", scd);
string ss = (string)cache.Get("SiteInfo");
} string newCache= (string)cache.Get("SiteInfo");
ViewBag.newCache = newCache; return View();
} }
}
我们对Student表启用缓存通知。
打开vs命令工具行,输入:aspnet_regsql -S LJJ-FF\LJJ -U sa -P 111111 -ed -d TestMvc -et -t Student

这样当数据表更新的时候,缓存就会失效。
public UserMenuEntityCollection GetUserMenuCollection(string language, int level)
{ UserMenuEntityCollection returnCollection = HttpContext.Current.Cache[className] as UserMenuEntityCollection;
if (returnCollection != null)
{
return returnCollection;
}
returnCollection = GetUserMenuFromDB(language, level); if (!SqlCacheDependencyAdmin.GetTablesEnabledForNotifications(ConfigurationManager.ConnectionStrings["AARTOConnectionString"].ConnectionString).Contains(tableName))
{
SqlCacheDependencyAdmin.EnableTableForNotifications(ConfigurationManager.ConnectionStrings["AARTOConnectionString"].ConnectionString, tableName);
}
string dataBaseName = "";
ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings["AARTOConnectionString"];
string[] connectParameterArray = connectionStringSettings.ConnectionString.Split(';');
foreach (string connectParameter in connectParameterArray)
{
if (connectParameter.Substring(, connectParameter.IndexOf("=")) == "Initial Catalog")
{
//dataBaseName = connectParameter.Substring(connectParameter.IndexOf("="));
dataBaseName = connectParameter.Substring(connectParameter.IndexOf("=") + );
break;
}
}
SqlCacheDependency sqlDependency = new SqlCacheDependency(dataBaseName, tableName);
HttpContext.Current.Cache.Insert(className, returnCollection, sqlDependency); return returnCollection;
}
利用反射取缓存代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Caching;
using System.Collections;
using System.Reflection;
using System.Data.SqlClient;
using System.Configuration;
using System.Data;
using SIL.AARTO.DAL.Entities; namespace SIL.AARTO.BLL.Utility.Cache
{
public abstract class AARTOCache
{
public static System.Web.Caching.Cache Cache = HttpContext.Current.Cache;
protected string className;
protected string tableName; protected static object GetCacheData(string className, string tableName)
{ Type typeEntity = Type.GetType("SIL.AARTO.DAL.Entities." + className + ",SIL.AARTO.DAL.Entities");
Type typeService = Type.GetType("SIL.AARTO.DAL.Services." + className + "Service,SIL.AARTO.DAL.Services");
object objEntity = Activator.CreateInstance(typeEntity);
object objService = Activator.CreateInstance(typeService); object result = Cache[tableName]; if (result == null)
{
string dataBaseName = "";
ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings["AARTOConnectionString"];
string[] connectParameterArray = connectionStringSettings.ConnectionString.Split(';');
foreach (string connectParameter in connectParameterArray)
{
if (connectParameter.Substring(, connectParameter.IndexOf("=")) == "Initial Catalog")
{
//dataBaseName = connectParameter.Substring(connectParameter.IndexOf("="));
dataBaseName = connectParameter.Substring(connectParameter.IndexOf("=") + );
break;
}
} foreach (MethodInfo info in typeService.GetMethods())
{
if (info.Name == "GetAll")
{
result = info.Invoke(objService, null);
//if (result != null)
//{
// SqlCacheDependencyAdmin.EnableNotifications(connectionStringSettings.ConnectionString);
// if (!SqlCacheDependencyAdmin.GetTablesEnabledForNotifications(connectionStringSettings.ConnectionString).Contains(tableName))
// {
// SqlCacheDependencyAdmin.EnableTableForNotifications(connectionStringSettings.ConnectionString, tableName);
// }
// SqlCacheDependency sqlCacheDependency = new SqlCacheDependency(dataBaseName, tableName);
// HttpContext.Current.Cache.Insert(tableName, result, sqlCacheDependency);
//}
break;
}
} } return result; } private static void OnRemoveQuotesCollection(string key, object val,
CacheItemRemovedReason r)
{
// Do something about the dependency Change
if (r == CacheItemRemovedReason.DependencyChanged)
{
HttpRuntime.Cache.Remove(key);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using SIL.AARTO.DAL.Entities; using SIL.AARTO.DAL.Services;
using System.Web.UI.WebControls;
using SIL.AARTO.BLL.Utility.UserMenu;
using System.Web;
using System.Web.Caching;
using System.Configuration; namespace SIL.AARTO.BLL.Utility.Cache
{
public class AARTOMenuLookUpCache : AARTOCache
{
//public readonly string className="AartoMenu";
//public readonly string tableName = "AARTOMenu"; public TList<AartoMenuLookup> GetAll()
{
className = "AartoMenuLookup";
tableName = "AARTOMenuLookup"; return GetCacheData(className, tableName) as TList<AartoMenuLookup>; }
} public class AARTOMenuCache : AARTOCache
{
public AARTOMenuCache()
{
className = "GenerateUserMenuByLanguageAndLevel";
tableName = "AARTOMenu";
}
private static AartoMenuService menuService = new AartoMenuService();
public TList<AartoMenu> GetAll()
{
className = "AartoMenu";
tableName = "AARTOMenu"; return GetCacheData(className, tableName) as TList<AartoMenu>; } public UserMenuEntityCollection GetUserMenuFromDB(string language, int level)
{
UserMenuEntityCollection returnCollection = new UserMenuEntityCollection();
UserMenuEntityCollection containerCollection = new UserMenuEntityCollection();
UserMenuEntityCollection currentCollection = new UserMenuEntityCollection();
//int currentLevel = 0;
int oldlevel = ; using (IDataReader reader = menuService.GenerateUserMenuByLanguageAndLevel(language, level))
{
while (reader.Read())
{
UserMenuEntity menu = GetUserMenuEntityFromDataReader(reader); if (menu.Level == )
{
returnCollection.Add(menu);
containerCollection.Add(menu);
}
else
{
if (oldlevel != menu.Level)
{
containerCollection.Clear(); foreach (UserMenuEntity menuEntity in currentCollection)
{
containerCollection.Add(menuEntity);
}
currentCollection.Clear();
oldlevel = menu.Level;
} currentCollection.Add(menu); CreateUserMenu(containerCollection, menu);
}
}
}
return returnCollection;
} public UserMenuEntityCollection GetUserMenuCollection(string language, int level)
{ UserMenuEntityCollection returnCollection = HttpContext.Current.Cache[className] as UserMenuEntityCollection;
if (returnCollection != null)
{
return returnCollection;
}
returnCollection = GetUserMenuFromDB(language, level); if (!SqlCacheDependencyAdmin.GetTablesEnabledForNotifications(ConfigurationManager.ConnectionStrings["AARTOConnectionString"].ConnectionString).Contains(tableName))
{
SqlCacheDependencyAdmin.EnableTableForNotifications(ConfigurationManager.ConnectionStrings["AARTOConnectionString"].ConnectionString, tableName);
}
string dataBaseName = "";
ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings["AARTOConnectionString"];
string[] connectParameterArray = connectionStringSettings.ConnectionString.Split(';');
foreach (string connectParameter in connectParameterArray)
{
if (connectParameter.Substring(, connectParameter.IndexOf("=")) == "Initial Catalog")
{
//dataBaseName = connectParameter.Substring(connectParameter.IndexOf("="));
dataBaseName = connectParameter.Substring(connectParameter.IndexOf("=") + );
break;
}
}
SqlCacheDependency sqlDependency = new SqlCacheDependency(dataBaseName, tableName);
HttpContext.Current.Cache.Insert(className, returnCollection, sqlDependency); return returnCollection;
} private void CreateUserMenu(UserMenuEntityCollection container, UserMenuEntity menu)
{
foreach (UserMenuEntity menuEntity in container)
{
if (menuEntity.AaMeID == menu.ParentAaMeID)
{
menu.ParentMenuEntity = menuEntity;
menuEntity.UserMenuList.Add(menu);
break;
}
}
} private UserMenuEntity GetUserMenuEntityFromDataReader(IDataReader reader)
{
UserMenuEntity userMenu = new UserMenuEntity();
userMenu.AaMeID = Convert.ToDecimal(reader["AaMeID"]);
userMenu.ParentAaMeID = reader["AaParentMeIDMeID"] == DBNull.Value ? : Convert.ToDecimal(reader["AaParentMeIDMeID"]);
userMenu.AMLMenuItemName = reader["AaMLMenuItemName"].ToString();
userMenu.PageID = reader["AaPageID"].ToString();
userMenu.UserRole = reader["AaUserRoleID"] == DBNull.Value ? : Convert.ToInt32(reader["AaUserRoleID"]);
userMenu.Level = Convert.ToInt32(reader["Level"]);
userMenu.AaMeOrderNo = Convert.ToInt32(reader["AaMeOrderNo"]);
userMenu.IsVisable = true;
userMenu.IsAarto = reader["IsAARTO"] == DBNull.Value ? false : Convert.ToBoolean(reader["IsAARTO"]);
userMenu.AaMePageURL = reader["AaPageURL"].ToString();
userMenu.IsNewWindow = reader["IsNewWindow"] == DBNull.Value ? false : Convert.ToBoolean(reader["IsNewWindow"]);
return userMenu;
} }
}
c#本地缓存当数据库表更改时,缓存失效。的更多相关文章
- 数据库表设计时一对一关系存在的必要性 数据库一对一、一对多、多对多设计 面试逻辑题3.31 sql server 查询某个表被哪些存储过程调用 DataTable根据字段去重 .Net Core Cors中间件解析 分析MySQL中哪些情况下数据库索引会失效
数据库表设计时一对一关系存在的必要性 2017年07月24日 10:01:07 阅读数:694 在表设计过程中,我无意中觉得一对一关系觉得好没道理,直接放到一张表中不就可以了吗?真是说,网上信息什么都 ...
- Oracle数据库表设计时的注意事项
表是Oracle数据库中最基本的对象之一.万丈高楼从平地起,这个基础对象对于数据库来说,非常重要.因为其设计是否合理,直接跟数据库的性能相关.从Oracle数据库菜鸟到数据库专家这个过程中,在表设计与 ...
- 关于redis的几件小事(八)缓存与数据库双写时的数据一致性
1.Cache aside pattern 这是最经典的 缓存+数据库 读写模式,操作如下: ①读的时候,先读缓存,缓存没有就读数据库,然后将取出的数据放到缓存,同时返回请求响应. ②更新的时候,先删 ...
- 缓存与数据库一致性之三:缓存穿透、缓存雪崩、key重建方案
一.缓存穿透预防及优化 缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,但是出于容错的考虑,如果从存储层查不到数据则不写入缓存层,如图 11-3 所示整个过程分为如下 3 步: 缓存层 ...
- 转载LINQ TO Entity 在数据库发生更改时更新实体数据模型 .edmx 文件
转载原出处:http://blog.csdn.net/litao2/article/details/8629335 在“模型浏览器”中,右击 .edmx 文件,然后选择“从数据库更新模型”. 模型更新 ...
- 面试前必知Redis面试题—缓存雪崩+穿透+缓存与数据库双写一致问题
今天来分享一下Redis几道常见的面试题: 如何解决缓存雪崩? 如何解决缓存穿透? 如何保证缓存与数据库双写时一致的问题? 一.缓存雪崩 1.1什么是缓存雪崩? 回顾一下我们为什么要用缓存(Redis ...
- 解决 MVC4 Code First 数据迁移 数据库发生更改导致调试失败解决方法(二)
文章转载自:http://www.cnblogs.com/amoniyibeizi/p/4486617.html 前几天学MVC过程中,遇到更改Model类以后,运行程序就会出现数据已更改的问题导致调 ...
- 缓存与数据库一致性之二:高并发下的key重建(先淘汰cache再写db)的问题
一.为什么数据会不一致 回顾一下上一篇文章<缓存与数据库一致性之一:缓存更新设计>中对缓存.数据库进行读写操作的流程. 写流程: (1)先淘汰cache (2)再写db 读流程: (1)先 ...
- EFCore 通过实体Model生成创建SQL Server数据库表脚本
在我们的项目中经常采用Model First这种方式先来设计数据库Model,然后通过Migration来生成数据库表结构,有些时候我们需要动态通过实体Model来创建数据库的表结构,特别是在创建像临 ...
随机推荐
- MVC5+EF6 入门完整教程5 :UI的一些改造
https://www.cnblogs.com/miro/p/4095165.html 上篇文章介绍了EF实现CRUD及一些基本的Html Helpers. 这次我们将会对之前的内容进行一些修改和重构 ...
- 在Linux系统上安装Git
Git是目前流行的非常好用的版本控制工具,这里介绍两种安装方式,1.yum安装,2.从github上下载最新的源码编译后安装 一.yum安装 1.在Linux上是有yum安装Git,非常简单,只需要一 ...
- 1.5 面试问题整理:cl
1.自我介绍2.介绍测试的项目> 期望答案:让你介绍项目,目的是想知道你参与过该项目后,对该项目的认识程度和认识层次,从而判断你在项目中到底起多大作用. 即:测试的流程.用例设计的方法.在项目中 ...
- 三值的排序 Sorting a Three-Valued Sequence(洛谷 P1459USACO2.1,IOI96Day2)
Sorting a Three-Valued Sequence IOI'96 - Day 2 Sorting is one of the most frequently performed compu ...
- oracle使用resultMap实现高级结果映射
resultMap的属性: 1.属性 id:resultMap的唯一标识.type:resulMap的映射结果类型(一般为Java实体类).2.子节点 id:一般对应数据库的主键 id,设置此项可以提 ...
- 《E=MC2或一个思想的故事》
思想是起点.一切行动都以萌芽状态孕藏在思想之中,以往所做过的一切均离不开思想. 他是个纯朴的人,喜欢在乡下静静地冥想. .而科学家们却非常清楚,那些最伟大的成就都是在静默中完成的.
- Unity相机跟随
固定相机跟随 这种相机有一个参考对象,它会保持与该参考对象固定的位置,跟随改参考对象发生移动 using UnityEngine; using System.Collections; public c ...
- 使用js处理后台返回的Date类型的数据
从后台返回的日期类型的数据,如果直接在前端进行显示的话,显示的就是一个从 1970-01-01 00:00:00到现在所经过的毫秒数,而在大多数业务中都不可能显示这个毫秒数,大多数都是显示一个正常的日 ...
- C语言字符串操作函数总结
转载来源:https://blog.csdn.net/qq_33757398/article/details/81212618 字符串相关操作头文件:string.h 1.strcpy函数 原型:st ...
- 全网最详细!搭建Hexo+Coding/Gitee,实现一键生成,同步部署
全网最全小白搭建Hexo+Gitee/Coding/Github 全网最全小白搭建Hexo+Gitee/Coding/Github 本站内容已全部转移到https://www.myyuns.ltd,具 ...