入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

使用 SqlCacheDependency 类在 ASP.NET 中缓存

创建时间:2006-12-12 投稿人: 浏览次数:985

使用 SqlCacheDependency 类在 ASP.NET 中缓存

疯一样的自由 11/22/2006 11:20:00 AM 我要投诉 使用 SqlCacheDependency 类在 ASP.NET 中缓存 

 

ASP.NET 允许您使用 SqlCacheDependency 类创建依赖于数据库中表或行的缓存项。当表中或特定行中发生更改时,带有依赖项的项便会失效,并会从缓存中移除。可以在 Microsoft SQL Server 7.0、SQL Server 2000 和 SQL Server 2005 中设置表的依赖项。如果您使用 SQL Server 2005,还可以设置特定记录的依赖项。

在某些方案中,使用带有 SQL 依赖项的缓存可显著提高应用程序的性能。例如,假定您正在构建一个从数据库显示产品信息的电子商务应用程序。如果不进行缓存,则每当用户要查看产品时,应用程序都必须从数据库请求数据。您可以在某一时刻将产品信息缓存一天,由于产品信息已经在内存中,因此可确保较快的响应时间,但是,当产品信息发生变化时,缓存的产品信息就会失去与数据库中数据的同步,且不同步的时间最长可达一天。

使用 SQL 缓存依赖项可以缓存产品信息,并创建一个数据库表或行更改的依赖项。当且仅当数据更改时,基于该数据的缓存项便会失效并会从缓存中移除。下次从缓存中请求该项时,如果该项不在缓存中,便可以再次向缓存中添加更新后的版本,并且可确保具有最新的数据。

SQL 缓存依赖项还可用于页输出缓存。例如,可以创建一个名为 ViewProduct.aspx 的页,用于显示有关特定产品的信息。可以将该页的缓存策略设置为 SQL 依赖项,就如为手动添加到缓存中的项所设置的依赖项一样。该页便会一直存储在缓存中,直至所依赖的表或行发生更改为止。当数据发生更改时,便会重新创建页,并将新创建的页再次存储在输出缓存中。

有关更多信息,请参见 ASP.NET 缓存概述。

ASP.NET SQL 缓存依赖项提供以下功能:

  • SQL 缓存依赖项可用于应用程序缓存和页输出缓存。

  • 可在 SQL Server 7.0 及更高版本中使用 SQL 缓存依赖项。

  • 可以在网络园(一台服务器上存在多个处理器)或网络场(多台服务器运行同一应用程序)中使用 SQL 缓存依赖项。

  • 与 SQL 缓存依赖项关联的数据库操作比较简单,因此不会给服务器带来很高的处理成本。

  • 在应用程序和 SQL Server 中配置 SQL 缓存依赖项不需要很精深的 SQL 知识。ASP.NET 中包括可以自动执行此配置的工具。另外,还可以使用 SqlCacheDependencyAdmin 类以编程方式配置 SQL 缓存依赖项。

ASP.NET 为 SQL Server 7.0 和 SQL Server 2000 的缓存依赖项实现了一个轮询模型。ASP.NET 进程内的一个线程会以指定的时间间隔轮询 SQL Server 数据库,以确定数据是否已更改。如果数据已更改,缓存依赖项便会失效,并从缓存中移除。可以在 Web.config 文件中以声明方式指定应用程序中的轮询间隔,也可以使用 SqlCacheDependency 类以编程方式指定此间隔。

对于 SQL Server 7.0 和 SQL Server 2000,SQL 缓存依赖项仅限于表级别的数据更改。可以将 ASP.NET 配置为轮询数据库来确定表中的更改,但不能确定特定行中的更改。

启用 SQL 缓存

为了在 SQL Server 7.0 和 SQL Server 2000 中使用 SQL 缓存依赖项,必须先将 SQL Server 配置为支持缓存依赖项。ASP.NET 提供了一些实用工具,可用于配置 SQL Server 上的 SQL 缓存,其中包括一个名为 Aspnet_regsql.exe 的工具和 SqlCacheDependencyAdmin 类。有关如何在 SQL Server 上启用 SQL 缓存依赖项的更多信息,请参见如何:使用缓存键依赖项缓存页输出。

SQL Server 2005 为缓存依赖项实现的模型不同于 SQL Server 7.0 和 SQL Server 2000 中的缓存依赖项模型。在 SQL Server 2005 中,不需要执行任何特殊的配置步骤来启用 SQL 缓存依赖项。此外,SQL Server 2005 还实现了一种更改通知模型,可以向订阅了通知的应用程序服务器发送通知,而不是依赖早期版本的 SQL Server 中必需的轮询模型。

SQL Server 2005 缓存依赖项在接收通知的更改类型方面更具灵活性。SQL Server 2005 监控对特定 SQL 命令的结果集的更改。如果数据库中发生了将修改该命令的结果集的更改,依赖项便会使缓存的项失效。此功能使得 SQL Server 2005 可以提供行级别的通知。

对用于测试更改的查询有一些要求。必须提供完全限定的表名,其中包括所有者名称(例如 dbo.authors)。总之,SQL 2005 通知支持 Select 查询和存储过程,支持多个查询和嵌套查询,但不支持聚合操作(例如 COUNT(*))。有关 SQL Server 2005 支持哪些查询以及通知规则的更多信息,请参见“SQL Books Online”(SQL 联机丛书)中的主题“Creating a Query for Notification”(创建通知查询)。

在对 SQL Server 7.0 或 SQL Server 2000 进行了缓存依赖项配置后,或是在 SQL Server 2005 中创建了适当的命令依赖项后,就可以配置您的应用程序来使用 SQL 缓存依赖项,如同配置任何其他缓存依赖项一样。例如,可以在 Web.config 文件中创建一个缓存配置文件,然后在应使用 SQL 缓存依赖项的每个页中引用该缓存配置文件。还可以在通过 SqlCacheDependency 类以编程方式启用 SQL 缓存依赖项后再使用它。有关更多信息,请参见如何:使用缓存键依赖项缓存页输出。

SqlCacheDependency 类 

注意:此类在 .NET Framework 2.0 版中是新增的。

在以下两者之间建立关系:一是在 ASP.NET 应用程序的 Cache 对象中存储的项;二是特定 SQL Server 数据库表或 SQL Server 2005 查询的结果。无法继承此类。

命名空间:System.Web.Caching
程序集:System.Web(在 system.web.dll 中)

语法语法
Visual Basic(声明)
PublicNotInheritableClass SqlCacheDependency
Inherits CacheDependency
Visual Basic(用法)
Dim instance As SqlCacheDependency
C#
public sealed class SqlCacheDependency : CacheDependency
C++
public ref class SqlCacheDependency sealed : public CacheDependency
J#
public final class SqlCacheDependency extends CacheDependency
JScript
public final class SqlCacheDependency extends CacheDependency
备注备注

SqlCacheDependency 类在所有受支持的 SQL Server 版本 (7.0, 2000, 2005) 上监视特定的 SQL Server 数据库表,以便在该表发生更改时,自动从 Cache 中删除与该表关联的项。

数据库表发生更改时,将自动删除缓存项,并向 Cache 中添加新版本的项。

在使用 SQL Server 2005 数据库时,SqlCacheDependency 类还支持与 System.Data.SqlClient.SqlDependency 类进行集成。使用 SQL Server 2005 的查询通知机制来检测使 SQL 查询结果无效的数据更改。与 SQL 查询关联的任何缓存项都将从 System.Web.Caching.Cache 中移除。

在使用 SQL Server 2005 时,可以使用 SqlCacheDependency 类向应用程序的 Cache 添加依赖于 SQL Server 数据库表或 SQL 查询的项。还可以将此类与 @ OutputCache 指令一起使用,以生成依赖于 SQL Server 数据库表的输出缓存的页或用户控件。最后,在使用 SQL Server 2005 时,可以将 SqlCacheDependency 类与 @ OutputCache 页指令一起使用,以生成依赖于 SQL 查询结果的输出缓存的页。对于用户控件,@ OutputCache 指令不支持使用 SQL Server 2005 的查询通知。

Note注意

为使此类在使用基于表的通知时正常工作,必须为数据库及要设置依赖项的任何表启用通知。可通过使用 SqlCacheDependencyAdmin 类的方法或 Aspnet_regsql.exe 命令行工具启用通知。同时,应用程序的 Web.config 文件中必须包含正确的配置设置。

SqlCacheDependency 对象与 SQL Server 2005 查询通知一起使用不需要任何显式配置。开发人员应参考 SQL Server 2005 联机丛书,以了解使用查询通知时允许的 Transact-SQL 查询类型的限制。

下面是一个 ASP.NET Web.config 文件示例,该文件对 SQL Server 数据库表启用了基于表的依赖项。

<configuration>
<connectionStrings>
<add name="Pubs" connectionString="Data Source=(local); Initial Catalog=pubs; Integrated Security=true"; providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<caching>
<sqlCacheDependency enabled = "true" pollTime = "60000" >
<databases>
<add name="pubs"
connectionString = "pubs"
pollTime = "9000000"
/>
</databases>
</sqlCacheDependency>
</caching>
</system.web>
</configuration>
Topic Location
Walkthrough: Using ASP.NET Output Caching with SQL Server Building ASP .NET Web Applications in Visual Studio
逐步解說:將 ASP.NET 輸出快取功能與 SQL Server 搭配使用 在 Visual Studio 中建置 ASP .NET Web 應用程式
示例示例

下面的代码示例使用 SqlDataSource 和 GridView 控件显示数据库表。加载页时,该页试图创建 SqlCacheDependency 对象。创建 SqlCacheDependency 对象后,该页向 Cache 添加一个项,该项在 SqlCacheDependency 对象上有一个依赖项。应使用与此处所示类似的异常处理。

Visual Basic 复制代码
<%@ Page Language="VB" Debug="True" %>
<%@ import Namespace="System.Data.SqlClient" %>
<script runat="server">
Sub Page_Load(Src AsObject, E As EventArgs)
" Declare the SqlCacheDependency instance, SqlDep.Dim SqlDep As SqlCacheDependency
" Check the Cache for the SqlSource key." If it isn"t there, create it with a dependency" on a SQL Server table using the SqlCacheDependency class.If Cache("SqlSource") IsNothing" Because of possible exceptions thrown when this" code runs, use Try...Catch...Finally syntax.Try" Instantiate SqlDep using the SqlCacheDependency constructor.
SqlDep = New SqlCacheDependency("Northwind", "Categories")
" Handle the DatabaseNotEnabledForNotificationException with" a call to the SqlCacheDependencyAdmin.EnableNotifications method.Catch exDBDis As DatabaseNotEnabledForNotificationException
Try
SqlCacheDependencyAdmin.EnableNotifications("Northwind")
" If the database does not have permissions set for creating tables," the UnauthorizedAccessException is thrown. Handle it by redirecting" to an error page.Catch exPerm As UnauthorizedAccessException
Response.Redirect("./ErrorPage.htm")
EndTry" Handle the TableNotEnabledForNotificationException with" a call to the SqlCacheDependencyAdmin.EnableTableForNotifications method.Catch exTabDis As TableNotEnabledForNotificationException
Try
SqlCacheDependencyAdmin.EnableTableForNotifications( _
"Northwind", "Categories")
" If a SqlException is thrown, redirect to an error page.Catch exc As SqlException
Response.Redirect("./ErrorPage.htm")
EndTry" If all the other code is successful, add MySource to the Cache" with a dependency on SqlDep. If the Categories table changes," MySource will be removed from the Cache. Then generate a message" that the data is newly created and added to the cache.Finally
Cache.Insert("SqlSource", Source1, SqlDep)
CacheMsg.Text = "The data object was created explicitly."EndTryElse
CacheMsg.Text = "The data was retrieved from the Cache."EndIfEndSub
</script>
<html>
<head>
</head>
<body>
<form runat="server">
<p>
</p>
<p>
<asp:SqlDataSource id="Source1" runat="server" SelectCommand="SELECT * FROM [Categories]" UpdateCommand="UPDATE [Categories] SET [CategoryName]=@CategoryName,[Description]=@Description,[Picture]=@Picture WHERE [CategoryID]=@CategoryID" ConnectionString="server="localhost";user id="bjctest";password="bjctest"; Database="Northwind""></asp:SqlDataSource>
<asp:GridView id="GridView1" runat="server" KeyFieldNames="CategoryID" AllowSorting="True" AllowPaging="True" DataSourceID="Source1"></asp:GridView>
</p>
<p>
</p>
<p>
<asp:Label id="CacheMsg" runat="server"></asp:Label>
</p>
</form>
</body>
</html>


SqlCacheDependencyAdmin 类 

注意:此类在 .NET Framework 2.0 版中是新增的。

在使用基于轮询的依赖项时,执行 SQL Server 数据库上需要的管理任务以支持 SqlCacheDependency 类。无法继承此类。

命名空间:System.Web.Caching
程序集:System.Web(在 system.web.dll 中)

语法语法
Visual Basic(声明)
PublicNotInheritableClass SqlCacheDependencyAdmin
Visual Basic(用法)
可对静态类的成员直接进行访问,无需类的实例。
C#
publicstaticclass SqlCacheDependencyAdmin
C++
public ref class SqlCacheDependencyAdmin abstract sealed
J#
public final class SqlCacheDependencyAdmin
JScript
public final class SqlCacheDependencyAdmin
备注备注

可以使用此类的方法以编程方式为 SQL Server 数据库及其表启用和禁用 SqlCacheDependency 对象更改通知。此外,此类使用 GetTablesEnabledForNotifications 方法获取有关为数据库中的哪些表启用更改通知的信息。但是,也可以使用 Aspnet_regsql 命令行工具管理 SQL Server 数据库及其表的更改通知。

Note注意

若要调用此类中的任何方法,用于访问 SQL Server 数据库的帐户必须具有创建表和存储过程的权限。若要启用特定表的通知,必须具有在该表上创建 SQL Server 触发器的权限。有关如何设置数据库权限的更多信息,请参见 SQL Server 文档。有关 ASP.NET 进程使用的帐户的更多信息,请参见 ASP.NET 模拟

示例示例

下面的代码示例是一个简单的 ASP.NET 页,用于启用和禁用 SQL Server 数据库表的更改通知。该示例使用 SqlCacheDependencyAdmin 对象管理数据库(在名为 MyConnectionString 的连接字符串中指定)中的更改通知。该示例包括两个文件,即一个定义用户界面的 .aspx 文件和一个包含 ASP.NET 事件的源代码的代码隐藏文件。

第一个示例为定义用户界面的 .aspx 文件。

C# 复制代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="cacheDependencyAdmincs.aspx.cs"
Inherits="cacheDependencyAdmincs" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html >
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Cache Dependency Administration</title>
</head>
<body>
<form id="form1" runat="server">
<table>
<tr>
<td colspan="2">
Database support for change notifications:
</td>
</tr>
<tr>
<td align="center">
<asp:Button ID="enableNotification" runat="server" Text="On" OnClick="enableNotification_Click" />
</td>
<td align="center">
<asp:Button ID="disableNotification" runat="server" Text="Off" OnClick="disableNotification_Click" />
</td>
</tr>
<tr>
<td colspan="2">
<asp:Label ID="enabledTablesMsg" runat="server" Text="Tables enabled for change notification:" />
</td>
</tr>
<tr>
<td colspan="2">
<asp:ListBox ID="enabledTables" runat="server" SelectionMode="multiple" /><br />
<asp:Button ID="disableTable" runat="server" Text="Disable selected table(s)" OnClick="disableTable_Click" />
</td>
</tr>
<tr>
<td colspan="2">
<asp:Label ID="tableEnableMsg" runat="server" Text="Enable change notification on table:" />
</td>
</tr>
<tr>
<td colspan="2">
<asp:TextBox ID="tableName" runat="server" /><br />
<asp:Button ID="enableTable" runat="server" Text="Enable table(s)" OnClick="enableTable_Click" />
<asp:Label id="enableTableErrorMsg" runat="server" Visible="false" />
</td>
</tr>
</table>
</form>
</body>
</html>

第二个示例为包含页事件的源代码的代码隐藏文件。

Visual Basic 复制代码
Partial Class cacheDependencyAdminvb
Inherits System.Web.UI.Page
ProtectedSub Page_Load(ByVal sender AsObject, ByVal e As System.EventArgs)
"Put the page into a default state.
enabledTables.Visible = True
disableTable.Visible = True
enabledTablesMsg.Text = "Tables enabled for change notification:"
tableName.Visible = True
enableTable.Visible = True
tableEnableMsg.Text = "Enable change notification on table(s):"
enableTableErrorMsg.Text = ""EndSubProtectedSub Page_PreRender(ByVal sender AsObject, ByVal e As System.EventArgs)
TryDim enabledTablesList AsString()
enabledTablesList = SqlCacheDependencyAdmin.GetTablesEnabledForNotifications( _
ConfigurationManager.ConnectionStrings("MyConnectionString").ConnectionString)
If enabledTablesList.Length > 0 Then
enabledTables.DataSource = enabledTablesList
enabledTables.DataBind()
Else
enabledTablesMsg.Text = "No tables are enabled for change notifications."
enabledTables.Visible = False
disableTable.Visible = FalseEndIfCatch ex As DatabaseNotEnabledForNotificationException
enabledTables.Visible = False
disableTable.Visible = False
enabledTablesMsg.Text = "Cache notifications are not enabled in this database."
tableName.Visible = False
enableTable.Visible = False
tableEnableMsg.Text = "Must enable database for notifications before enabling tables."EndTryEndSubProtectedSub enableNotification_Click(ByVal sender AsObject, ByVal e As System.EventArgs)
SqlCacheDependencyAdmin.EnableNotifications( _
ConfigurationManager.ConnectionStrings("MyConnectionString").ConnectionString)
EndSubProtectedSub disableNotification_Click(ByVal sender AsObject, ByVal e As System.EventArgs)
SqlCacheDependencyAdmin.DisableNotifications( _
ConfigurationManager.ConnectionStrings("MyConnectionString").ConnectionString)
EndSubProtectedSub disableTable_Click(ByVal sender AsObject, ByVal e As System.EventArgs)
ForEach item As ListItem In enabledTables.Items
If item.Selected Then
SqlCacheDependencyAdmin.DisableTableForNotifications( _
ConfigurationManager.ConnectionStrings("MyConnectionString").ConnectionString, _
item.Text)
EndIfNextEndSubProtectedSub enableTable_Click(ByVal sender AsObject, ByVal e As System.EventArgs)
TryIf tableName.Text.Contains(";") ThenDim tables AsString()
tables = tableName.Text.Split(New [Char]() {";"c})
For i AsInteger = 0 To tables.Length - 1
tables(i) = tables(i).Trim
Next
SqlCacheDependencyAdmin.EnableTableForNotifications( _
ConfigurationManager.ConnectionStrings("MyConnectionString").ConnectionString, _
tables)
Else
SqlCacheDependencyAdmin.EnableTableForNotifications( _
ConfigurationManager.ConnectionStrings("MyConnectionString").ConnectionString, _
tableName.Text)
EndIfCatch ex As HttpException
enableTableErrorMsg.Text = "<br />" & _
"An error occured enabling a table.<br />" & _
"The error message was: " & _
ex.Message
enableTableErrorMsg.Visible = TrueEndTryEndSubEndClass
C# 复制代码
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;
using System.Web.Caching;
public partial class cacheDependencyAdmincs : System.Web.UI.Page
{
protectedvoid Page_Load(object sender, EventArgs e)
{
// Put page in default state.
enabledTables.Visible = true;
disableTable.Visible = true;
enabledTablesMsg.Text = "Tables enabled for change notification:";
tableName.Visible = true;
enableTable.Visible = true;
tableEnableMsg.Text = "Enable change notification on table(s):";
enableTableErrorMsg.Visible = false;
}
protectedvoid Page_PreRender(object sender, EventArgs e)
{
try
{
string[] enabledTablesList =
SqlCacheDependencyAdmin.GetTablesEnabledForNotifications(
ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
if (enabledTablesList.Length > 0)
{
enabledTables.DataSource = enabledTablesList;
enabledTables.DataBind();
}
else
{
enabledTablesMsg.Text = "No tables are enabled for change notifications.";
enabledTables.Visible = false;
disableTable.Visible = false;
}
}
catch (DatabaseNotEnabledForNotificationException ex)
{
enabledTables.Visible = false;
disableTable.Visible = false;
enabledTablesMsg.Text = "Cache notifications are not enabled inthis database.";
tableName.Visible = false;
enableTable.Visible = false;
tableEnableMsg.Text = "Must enable database for notifications before enabling tables";
}
}
protectedvoid enableNotification_Click(object sender, EventArgs e)
{
SqlCacheDependencyAdmin.EnableNotifications(
ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
}
protectedvoid disableNotification_Click(object sender, EventArgs e)
{
SqlCacheDependencyAdmin.DisableNotifications(
ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
}
protectedvoid disableTable_Click(object sender, EventArgs e)
{
foreach (ListItem item in enabledTables.Items)
{
if (item.Selected)
{
SqlCacheDependencyAdmin.DisableTableForNotifications(
ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString,
item.Text);
}
}
}
protectedvoid enableTable_Click(object sender, EventArgs e)
{
try
{
if (tableName.Text.Contains(";"))
{
string[] tables = tableName.Text.Split(new Char[] { ";" });
for (int i = 0; i < tables.Length; i++)
tables[i] = tables[i].Trim();
SqlCacheDependencyAdmin.EnableTableForNotifications(
ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString,
tables);
}
else
{
SqlCacheDependencyAdmin.EnableTableForNotifications(
ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString,
tableName.Text);
}
}
catch (HttpException ex)
{
enableTableErrorMsg.Text = "<br />" +
"An error occured enabling a table.<br />" +
"The error message was: " +
ex.Message;
enableTableErrorMsg.Visible = true;
}
}
}

声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。