缓存和SqlCacheDependency特性【转】

这几天学习了缓存,但在实际使用中还有许多问题,所以网上看了下资料,下面的一篇文章是在【webabcd】的博客中看到,感觉写的挺好的.......

介绍
存是在计算中广泛使用的一种技术,通过将经常访问的数据或存取开销较大的数据保留在内存或硬盘中来提高性能。在 Web 应用程序的上下文中,缓存用于在 HTTP 请求之间保留页或数据,在重用它们时可以不必耗费资源重新创建。


关键
1、@OutputCache指令中的属性:
    Duration - 缓存时间(秒)
    VaryByParam - 根据使用 POST 或 GET 发送的名称/值对来改变缓存的结果(多参数用分号隔开)
    VaryByControl - 根据用户控件中的控件来改变缓存的片段(值是控件ID,多控件用分号隔开)
    CacheProfile - 调用配置文件中设置的缓存时间

2、增加数据缓存时用Cache.Insert,可以指定缓存时间

3、替换缓存(Substitution)- 回调函数要是静态的

4、SqlCacheDependency
配置文件中的配置

  <system.web>
    
<caching>
      
<sqlCacheDependency enabled="true" pollTime="轮询时间(毫秒)">
        
<databases>
          
<add name="名字" connectionStringName="连接字符串的名字" />
        
</databases>
      
</sqlCacheDependency>
      
<!-- 如果是SqlServer2005的话,则只需如下设置,因为SqlServer支持基于通知的缓存失效
      <sqlCacheDependency enabled="true" />
      
-->
    
</caching>
  
</system.web>

如果不是SqlServer2005的话,应该使用aspnet_regsql注册一下
aspnet_regsql.exe -S "server" -E -d "database" -ed
aspnet_regsql.exe -S "server" -E -d "database" -et -t "table"
如果是Sql验证的话要把-E换成,-U(用户名),-P(密码)


示例
页面输出缓存
Cahce/Page.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Page.aspx.cs"
    Inherits
="Cahce_Page" Title="页面输出缓存" 
%>

<%@ OutputCache Duration="10" VaryByParam="none" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    
<p>
        Duration="10" VaryByParam="none"
    
</p>
    
<p>
        
<%=DateTime.Now %>
    
</p>
</asp:Content>

API操作缓存
Cahce/Page.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class Cahce_Page : System.Web.UI.Page
{
    
protected void Page_Load(object sender, EventArgs e)
    
{
        
/* 通过API设置缓存 不常用啊
        
        // 相当于@OutputCache指令中的Duration属性
        Response.Cache.SetExpires(DateTime.Now.AddSeconds(10));
        // 以指定响应能由客户端和共享(代理)缓存进行缓存。
        Response.Cache.SetCacheability(HttpCacheability.Public);

        // 过期时间可调
        Response.Cache.SetSlidingExpiration(true);
        
        
*/

    }

}

页面输出缓存(VaryByParam)
Cahce/PageByParam.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="PageByParam.aspx.cs"
    Inherits
="Cahce_PageByParam" Title="页面输出缓存(VaryByParam)" 
%>

<%@ OutputCache CacheProfile="CacheTest" VaryByParam="p1;p2" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    
<p>
        CacheProfile="CacheTest" VaryByParam="p1;p2"
        
<br />
        CacheProfile="CacheTest" - 从web.config中读信息
        
<br />
        get或post方式都行
    
</p>
    
<p>
        
<href="?p1=a&p2=b">第一组</a>
        
<br />
        
<href="?p1=c&p2=d">第二组</a>
        
<br />
        
<href="?p1=e&p2=f">第三组</a>
    
</p>
    
<p>
        
<%=DateTime.Now %>
    
</p>
</asp:Content>

上面页所需的web.config中的配置
  <system.web>
    
<caching>
      
<outputCacheSettings>
        
<outputCacheProfiles>
          
<add name="CacheTest" duration="10" />
        
</outputCacheProfiles>
      
</outputCacheSettings>
    
</caching>
  
</system.web>

页面输出缓存(VaryByControl)
Cahce/CacheControl.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CacheControl.ascx.cs"
    Inherits
="Cahce_CacheControl" 
%>
<%@ OutputCache Duration="10" VaryByControl="DropDownList1" %>
<p>
    
<%=DateTime.Now %>
</p>
<p>
    
<asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="XmlDataSource1"
        DataTextField
="text" DataValueField="value">
    
</asp:DropDownList><asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="~/Config/DropDownListData.xml">
    
</asp:XmlDataSource>
</p>
<p>
    
<asp:Button ID="btn" runat="Server" Text="提交" />
</p>

Cahce/PageByControl.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="PageByControl.aspx.cs"
    Inherits
="Cahce_PageByControl" Title="页面输出缓存(VaryByControl)" 
%>

<%@ Register Src="CacheControl.ascx" TagName="CacheControl" TagPrefix="uc1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    
<p>
        未经缓存设置的容器页:
        
<%=DateTime.Now %>
    
</p>
    
<p>
        经过VaryByControl设置的用户控件,根据DropDownList的不同缓存不同的内容(用户控件中的@OutputCache指令为Duration="10"
        VaryByControl="DropDownList1"):
<br />
        
<uc1:CacheControl ID="CacheControl1" runat="server" />
    
</p>
</asp:Content>

数据缓存
Cahce/Data.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Data.aspx.cs"
    Inherits
="Cahce_Data" Title="数据缓存" 
%>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    
<p>
        
<asp:Label ID="lbl" runat="server" />
    
</p>
</asp:Content>

Cahce/Data.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class Cahce_Data : System.Web.UI.Page
{
    
protected void Page_Load(object sender, EventArgs e)
    
{
        
// 一看就懂
        if (Cache["key"== null)
        
{
            Cache.Insert(
"key", DateTime.Now, null, DateTime.Now.AddSeconds(10), TimeSpan.Zero);
        }


        DateTime dt 
= (DateTime)Cache["key"];
        lbl.Text 
= dt.ToString();
    }

}


替换缓存(部分区域强行不使用缓存)
Cahce/Substitution.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Substitution.aspx.cs"
    Inherits
="Cahce_Substitution" Title="替换缓存(部分区域强行不使用缓存)" 
%>

<%@ OutputCache Duration="10" VaryByParam="none" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    
<p>
        Duration="10" VaryByParam="none"
    
</p>
    
<p>
        
<%=DateTime.Now %>
    
</p>
    
<p>
        API 向返回当前日期的静态方法中插入动态回调,此回调在每次请求时都会执行
<br />
        
<% Response.WriteSubstitution(new HttpResponseSubstitutionCallback(GetTime)); %>
    
</p>
    
<p>
        使用Substitution 控件插入动态内容
<br />
        
<asp:Substitution ID="Substitution1" runat="server" MethodName="GetTime" />
    
</p>
</asp:Content>

Cahce/Substitution.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class Cahce_Substitution : System.Web.UI.Page
{
    
protected void Page_Load(object sender, EventArgs e)
    
{

    }


    
// 回调函数所调的静态方法
    public static string GetTime(HttpContext context)
    
{
        
return DateTime.Now.ToString();
    }

}


SqlCacheDependency
页的Sql缓存
Cahce/SqlCachePage.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="SqlCachePage.aspx.cs"
    Inherits
="Cahce_SqlCachePage" Title="页的Sql缓存" 
%>

<%@ OutputCache Duration="999999" SqlDependency="VS2005_Test:sqlcache" VaryByParam="none" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    
<p>
        Duration="999999" SqlDependency="VS2005_Test:sqlcache" VaryByParam="none"
<br />
        如果是SqlServer2005则改成SqlDependency="CommandNotification
<br />
        注意配置文件中的配置
    
</p>
    
<p>
        
<%=DateTime.Now %>
    
</p>
</asp:Content>

数据源控件的Sql缓存
Cahce/SqlCachePage.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="SqlCacheDataSourceControl.aspx.cs"
    Inherits
="Cahce_SqlCacheDataSourceControl" Title="数据源控件的Sql缓存" 
%>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    
<p>
        DataSource控件设置如下属性:EnableCaching="True" SqlCacheDependency="VS2005_Test:sqlcache"
        CacheDuration="Infinite"
<br />
        如果是SqlServer2005则改成SqlDependency="CommandNotification
<br />
        注意配置文件中的配置
    
</p>
    
<p>
        
<%=DateTime.Now %>
    
</p>
    
<p>
        
<asp:SqlDataSource ID="SqlDataSource1" runat="server" EnableCaching="True" SqlCacheDependency="VS2005_Test:sqlcache"
            CacheDuration
="Infinite" ConnectionString="<%$ ConnectionStrings:SqlConnectionString %>"
            SelectCommand
="SELECT * FROM [SqlCache]"></asp:SqlDataSource>
        
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" AllowSorting="True">
        
</asp:GridView>
    
</p>
</asp:Content>

web.config中的相关配置
  <connectionStrings>
    
<add name="SqlConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\VS2005_Test.mdf;Integrated Security=True;User Instance=True"
      providerName
="System.Data.SqlClient" />
  
</connectionStrings>
  
<system.web>
    
<caching>
      
<sqlCacheDependency enabled="true" pollTime="10000">
        
<databases>
          
<add name="VS2005_Test" connectionStringName="SqlConnectionString" />
        
</databases>
      
</sqlCacheDependency>
      
<!-- 如果是SqlServer2005的话,则只需如下设置,因为SqlServer支持基于通知的缓存失效
      <sqlCacheDependency enabled="true" />
      
-->
    
</caching>
  
</system.web>



注意
Sql Server 2005 基于通知的缓存失效,不用aspnet_regsql设置,要设置属性SqlDependency="CommandNotification"。在首次执行某 SQL 查询之前,必须在应用程序某处调用 System.Data.SqlClient.SqlDependency.Start() 方法。此方法应放在 global.asax 文件的 Application_Start() 事件中。因为Sql Server 2005 基于通知的缓存失效对支持查询通知的查询语法有许多限制,所以我觉得最好先别用,而是使用轮询机制。在使用轮询机制时如本例子中的SqlCacheDependency="VS2005_Test:sqlcache",冒号前面是配置文件中配置的相关值指向数据库连接,后面是启用SqlCache的表名,注意区分大小写。


OK
[源码下载]
 

 

再给大家补充个例子,也是网上找到的.....

第一步
  修改web,config
  <!--定义数据库连接-->
  <connectionStrings>
   <add name="NorthwindConnectionString" connectionString="Server=USERRYR\DB;Database=Northwind;UID=sa;pwd=密码" providerName="System.Data.SqlClient"/>
  </connectionStrings>
  <system.web>
   <!-- 定义缓存策略-->
   <caching>
   <sqlCacheDependency enabled="true" pollTime="10000">
   <databases>
   <!--
   name:必需的 String 属性。
   要添加到配置集合中的 SqlCacheDependencyDatabase 对象的名称。
   此名称用作 @ OutputCache 指令上 SqlDependency 属性的一部分。
   pollTime:设置 SqlCacheDependency 轮询数据库表以查看是否发生更改的频率(以毫秒计算)。这儿是一个测试,所以设为10秒,请加大此值
   -->
   <add connectionStringName="NorthwindConnectionString" name="Categories"/>
   </databases>
   </sqlCacheDependency>
   </caching>
  </system.web>
  第二步.定义cachedData测试类
  using System;
  using System.Data;
  using System.Configuration;
  using System.Web;
  using System.Web.Security;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  using System.Web.UI.WebControls.WebParts;
  using System.Web.UI.HtmlControls;
  using System.Web.Caching;
  using System.Data.SqlClient;
  /// <summary>
  /// Summary description for CachedData
  /// </summary>
  public class CachedData
  {
   private string Key;
   private string _Source;
   /// <summary>
   /// 指示数据从哪儿读取的
   /// </summary>
   public string Source { get { return _Source; } }
  public CachedData()
  {
   Key = "Categories";
   _Source = "未知";
  }
   //读取数据
   public DataView getFromCache() {
   if (HttpRuntime.Cache[Key] == null)
   {
   //取数据
   SqlConnection conn = new SqlConnection();
   conn.ConnectionString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;
   SqlCommand comm = new SqlCommand("SELECT [CategoryID], [CategoryName], [Description] FROM [Categories]", conn);
   SqlDataAdapter sda = new SqlDataAdapter(comm);
   DataSet ds = new DataSet();
   conn.Open();
   sda.Fill(ds);
   DataView dv = ds.Tables[0].DefaultView;
   conn.Close();
   //启用更改通知
   SqlCacheDependencyAdmin.EnableNotifications(ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString);
   //连接到 SQL Server 数据库并为 SqlCacheDependency 更改通知准备数据库表
   SqlCacheDependencyAdmin.EnableTableForNotifications(ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString, "Categories");
   //制定缓存策略
   SqlCacheDependency scd = new SqlCacheDependency("Categories", "Categories");
   //插入缓存
   HttpRuntime.Cache.Insert(Key, dv, scd);
   _Source = "Database";
   return dv;
   }
   else {
   //从缓存中取值
   _Source = "cache";
   return (DataView)HttpRuntime.Cache[Key];
  
   }
   }
  }
  3.测试页面
  <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml" >
  <head runat="server">
   <title>Untitled Page</title>
  </head>
  <body>
   <form id="form1" runat="server">
   <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
   <asp:DataGrid runat="server" ID="Repeater1"></asp:DataGrid>&nbsp;
   </form>
  </body>
  </html>
  其对应cs文件
  using System;
  using System.Data;
  using System.Data.SqlClient;
  using System.Configuration;
  using System.Web;
  using System.Web.Security;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  using System.Web.UI.WebControls.WebParts;
  using System.Web.UI.HtmlControls;
  public partial class _Default : System.Web.UI.Page
  {
   protected void Page_Load(object sender, EventArgs e)
   {
  
   BindRepeater1();
  
   }
   private void BindRepeater1(){
   CachedData cd=new CachedData();
   this.Repeater1.DataSource = cd.getFromCache();
   this.Repeater1.DataBind();
   this.Label1.Text = cd.Source;
   }
  }

 

好了,到这里结束了,希望对大家有帮助,个人感觉轮询数据库表还是很好用的,使用缓存后替换固然好,但是有时候还是不方便......

posted on 2009-03-18 18:27  ToKens  阅读(478)  评论(0编辑  收藏  举报