ASP.NET的缓存依赖机制-SQL缓存依赖篇
高效使用使用SQL缓存依赖
ASP.NET Framework新增的一个非常强大的功能是SQL缓存依赖。该功能允许底层数据库中的数据修改时,自动地重新载入缓存的数据。
在使用绝对缓存过期策略或者弹性缓存过期策略时有一个权衡,对于性能和陈旧数据的权衡。例如,如果在内存中缓存数据20秒,则这20秒内显示的数据可能是过期的。
对于大多数应用程序来说,就算显示过期数据也没什么关系。例如,如果我们构建一个论坛讨论区,则每个用户都能接受新的主题可能不是实时显示的。
然而,某些类型的应用程序则绝对不能有陈旧数据。例如,如果我们创建一个股票交易网站或者拍卖网站,那么每一秒的数据都很关键。
ASP.NET Framework支持的SQL缓存依赖使得使用缓存时可以充分利用缓存,并且最小化陈旧数据。当使用SQL缓存依赖时,可以自动监测底层数据库中的数据是否变更,并刷新缓存中的数据。
ASP.NET Framework支持两种类型的SQL缓存依赖:轮询和推。可以对任何最近版本的Microsoft SQL Server,包括Microsoft SQL Server 2005 Express、Microsoft SQL Server 2000和Microsoft SQL Server 7.0,使用轮询SQL缓存依赖。第二种类型的缓存依赖——推SQL缓存依赖则只能用于Microsoft SQL Server 2005和Microsoft SQL Server 2005 Express,因为它依赖SQL Server 2005 Service Broker。
可以对页面输出缓存、数据源控件缓存和数据缓存使用任意类型的SQL缓存依赖。接下来将依次讨论每一种场景。
4.6.1 使用轮询SQL缓存依赖
轮询SQL缓存依赖是最灵活的SQL缓存依赖类型,所以对大多数应用程序来说,推荐使用轮询SQL缓存依赖。可以使用轮询SQL缓存依赖来检测数据库表的修改。
实质上,轮询SQL缓存依赖使用数据库触发器。当表被修改时,触发器被触发,名为AspNet_ SqlCacheTablesForChangeNotification的数据库表的一行数据将被更新,用来记录表被修改的情况。
ASP.NET Framework使用一个后台线程,用来定期轮询数据库表的修改信息。如果有修改,则依赖于数据库表的缓存项目从缓存中移除。
如果使用轮询SQL缓存依赖,则可以消除大多数和数据库的通信消费。如果数据库表还没有更改, Web服务器和数据库服务器之间唯一的通信是检查AspNet_SqlCacheTablesForChange- Notification表的修改的查询。
因为轮询SQL缓存依赖必须轮询数据库的修改,使用轮询SQL缓存依赖的缓存项目只有在数据修改时才会立即失效。轮询时间间隔的大小决定了缓存数据的陈旧程度,这个时间间隔可为任意需要的值。
4.6.2 配置轮询SQL缓存依赖
在使用轮询SQL缓存依赖之前,必须执行下面两步配置。
(1) 必须对一个或多个数据库表启用SQL缓存依赖。
(2) 必须在Web配置文件中配置SQL缓存依赖。
让我们分别讨论每一步。
1. 为轮询SQL缓存依赖配置数据库
可以使用框架中的SqlCacheDependencyAdmin类来配置SQL Server数据库以支持轮询SQL缓存依赖。该类包含如下方法。
l DisableNotifications——用于禁用数据库轮询SQL缓存依赖。移除所有用于表和存储过程的轮询缓存依赖。
l DisableTableForNotification——用于禁用特定的数据库表的轮询SQL缓存依赖。
l EnableNotifications——通过添加所有必需的数据库对象,启用数据库的轮询SQL缓存依赖。
l EnableTableForNotifications——启用特定数据库表的轮询SQL缓存依赖。
l GetTablesEnabledForNotifications——用于返回所有启用了轮询SQL缓存依赖的表。
不应该在ASP.NET页面中使用SqlCacheDependencyAdmin类,因为调用该类的方法需要创建表、存储过程和trigger。出于安全考虑,ASP.NET进程不应该被赋予这些权限,而是应该在一个命令行工具中使用SqlCacheDependencyAdmin类。
ASP.NET Framework包括一个名为aspnet_regsql的命令行工具,可用它来配置数据库以支持轮询SQL缓存依赖。该工具可以用于Microsoft SQL Server 7.0、Microsoft SQL Server 2000和Microsoft SQL Server 2005。遗憾的是,aspnet_regsql的命令行工具不支持本地Microsoft SQL Server 2005实例(不过我们马上会修复该限制)。
aspnet_regsql工具存放在下面文件夹中:
c:\Windows\Microsoft.NET\Framework\v2.0.50727
注解 如果打开Microsoft .NET Framework SDK程序组的SDK命令行提示程序,则不需要浏览Microsoft. NET目录就能执行aspnet_regsql命令行工具。
执行下面的命令可启用Pubs数据库的SQL缓存依赖:
aspnet_regsql -C "Data Source=localhost;Integrated Security=True;Initial
Catalog=Pubs" -ed
该命令将创建AspNet_SqlCacheTablesForChangeNotification数据库表,并添加一组存储过程到连接字串指定的数据库。
启用一个数据库之后,就可以用如下命令来启用特定表的SQL缓存依赖:
aspnet_regsql -C "Data Source=localhost;Integrated Security=True;Initial
Catalog=Pubs" -et -t Titles
该命令启用了Titles数据库表的SQL缓存依赖。它会给Titles数据库表创建一个新的trigger,并添加一行新记录到AspNet_SqlCacheTablesForChangeNotification表。
遗憾的是,不能使用标准的aspnet_regsql工具来启用本地SQL Server 2005 Express数据库实例的轮询SQL缓存依赖。此工具不允许在连接字符串中使用AttachDBFileName参数。
为了解除该限制,我编写了一个名为enableNotifications的自定义命令行工具,可以用它来处理本地SQL Express数据库。该工具包含在随书附带资源中。
要使用enableNotifications工具,先打开命令行工具,然后浏览包含本地SQL Express数据库的文件夹。接着,执行需要启用轮询SQL缓存依赖的数据库文件的名称和数据表的名称的命令。例如,下面的命令启用了MyDatabase.mdf数据库中的Movies数据库:
enableNotifications "MyDatabase.mdf" "Movies"
enableNotifications工具只能处理Microsoft SQL Server Express 2005数据库的实例。不能使用该工具处理其他版本的Microsoft SQL Server。
注意 当使用enableNotifications工具时,必须先浏览希望启用轮询SQL缓存依赖的数据所在的文件夹。
2. 为轮询SQL缓存依赖配置应用程序
设置数据库支持轮询SQL缓存依赖,必须要配置应用程序才能轮询数据库。可以使用Web配置文件中的caching元素的sqlCacheDependency子元素来配置轮询SQL缓存依赖。
例如,代码清单4-41所示的文件使得应用程序每5秒钟(5 000毫秒)对AspNet_SqlCacheTables- ForChangeNotification表进行一次轮询,观察是否有更改。
代码清单4-41 Web.Config
<configuration>
<connectionStrings>
<add name=”Movies” connectionString=”Data Source=.\SQLEXPRESS;
AttachDbFilename=|DataDirectory|MyDatabase.mdf;Integrated Security=True;
User Instance=True” />
</connectionStrings>
<system.web>
<caching>
<sqlCacheDependency enabled=”true” pollTime=”5000”>
<databases>
<add
name=”MyDatabase”
connectionStringName=”Movies” />
</databases>
</sqlCacheDependency>
</caching>
</system.web>
</configuration>
4.6.3 对页面输出缓存使用轮询SQL缓存依赖
配置好轮询SQL缓存依赖后,就能对页面输出缓存使用SQL依赖了。例如,代码清单4-42所示的页面被输出缓存了,直到Movies数据库表被修改,缓存才失效。
代码清单4-42 PollingSQLOutputCache.aspx
<%@ Page Language="C#" %>
<%@ OutputCache Duration="9999" VaryByParam="none"
SqlDependency="MyDatabase:Movies" %>
<!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 id="Head1" runat="server">
<title>Polling SQL Output Cache</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<%= DateTime.Now.ToString("T") %>
<hr />
<asp:GridView
id="grdMovies"
DataSourceID="srcMovies"
Runat="server" />
<asp:SqlDataSource
id="srcMovies"
ConnectionString="<%$ ConnectionStrings:Movies %>"
SelectCommand="SELECT Title, Director FROM Movies"
Runat="server" />
</div>
</form>
</body>
</html>
代码清单4-42所示的页面包含了一个带有sqlDependency特性的<%@ OutputCache %>指令。SqlDependency特性的值为Web配置文件中启用了SQL依赖的数据库和数据库表的名称。
如果在浏览器中打开如代码清单4-42所示的页面,并且多次单击浏览器的重新载入按钮,你会注意到显示的时间不会变,因为该页被输出缓存了(见图4-16)。
图4-16 对页面输出缓存使用轮询SQL缓存依赖
然而,当修改Movies数据库表时,页面缓存将会自动失效(5秒钟内)。再次单击重新载入按钮时,会显示修改的数据。
如果希望让一个页面依赖多个数据库表,则需要将sqlDependecy特性设置为一组用分号分隔的数据库和数据库表名的列表。
注解 也可以在一个用户控件中使用<%@ OutputCache %> 指令来使用轮询SQL缓存依赖。也就是说,可以使用轮询SQL缓存依赖来实现部分页面缓存。
4.6.4 对数据源缓存使用轮询SQL缓存依赖
要对SqlDataSource和ObjectDataSource控件使用轮询SQL缓存依赖,只需要设置sqlCache- Dependency属性。例如,代码清单4-43所示的页面缓存了SqlDataSource控件的输出,直到Movies数据库表被修改,它才失效。
代码清单4-43 PollingSQLDataSourceCache.aspx
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void srcMovies_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
lblMessage.Text = "Retrieving data from database";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Polling SQL DataSource Cache</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label
id="lblMessage"
EnableViewState="false"
Runat="server" />
<hr />
<asp:GridView
id="grdMovies"
DataSourceID="srcMovies"
Runat="server" />
<asp:SqlDataSource
id="srcMovies"
ConnectionString="<%$ ConnectionStrings:Movies %>"
SelectCommand="SELECT Title, Director FROM Movies"
EnableCaching="true"
SqlCacheDependency="MyDatabase:Movies"
OnSelecting="srcMovies_Selecting"
Runat="server" />
</div>
</form>
</body>
</html>
在代码清单4-43中,SqlDataSource控件包括了EnableCaching属性和SqlCacheDependency属性。数据库名和数据库表名都分配了SqlCacheDependency属性(数据库名必须与配置在Web配置文件<sqlCacheDependency>元素中的数据库名相对应)。
如果需要监视多个数据库表,则要给SqlCacheDependency属性指派一组用分号分隔的数据库和数据库表的名称列表。
4.6.5 对数据缓存使用轮询SQL缓存依赖
我们也可以对Cache对象使用轮询SQL缓存依赖,用SqlCacheDependency对象来代表一个轮询SQL缓存依赖。
例如,代码清单4-44所示的页面创建了一个SqlCacheDependency对象,它代表Movies数据库表。当DataTable添加到Cache对象时,DataTable就关联到SqlCacheDependency对象。
代码清单4-44 PollingSQLDataCache.aspx
<%@ Page Language="C#" Trace="true" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Web.Configuration" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void Page_Load()
{
DataTable movies = (DataTable)Cache["Movies"];
if (movies == null)
{
movies = GetMoviesFromDB();
SqlCacheDependency sqlDepend = new SqlCacheDependency("MyDatabase", "Movies");
Cache.Insert("Movies", movies, sqlDepend);
}
grdMovies.DataSource = movies;
grdMovies.DataBind();
}
private DataTable GetMoviesFromDB()
{
Trace.Warn("Retrieving data from database");
string conString = WebConfigurationManager.ConnectionStrings["Movies"].ConnectionString;
SqlDataAdapter dad = new SqlDataAdapter("SELECT Title,Director FROM Movies", conString);
DataTable movies = new DataTable();
dad.Fill(movies);
return movies;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Polling SQL Data Cache</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView
id="grdMovies"
Runat="server" />
</div>
</form>
</body>
</html>
代码清单4-44中创建了SqlCacheDependency类的一个实例。一个数据库名和表名传递给SqlCacheDependency类的构造函数。当DataTable添加到Cache时,该类就用作Cache.Insert()的一个参数。
注解 如果需要创建多个数据库表的依赖,则需要创建多个SqlCacheDependency对象并用Aggregate- CacheDependency类的实例表示多个依赖。
4.6.6 使用推SQL缓存依赖
在使用Microsoft SQL Server 2005时,除了轮询SQL缓存依赖,还可以使用推SQL缓存依赖。Microsoft SQL Server 2005包含一个名为查询通知的功能,它在后台使用Microsoft SQL Server 2005的Service Broker。这个Service Broker可以在数据库中的数据变更时自动给应用程序发送一个消息。
注意 可以用SQL Server Express创建两种类型的数据库:本地和服务器数据库。不应对本地数据库使用推依赖,而是只能对服务器数据库使用推依赖。
不能使用Visual Web Developer创建一个服务器数据库。只能使用完全功能的Visual Studio 2008或者从Microsoft MSDN网站(msdn.microsoft.com)下载Microsoft SQL Server Management Studio Express来创建服务器数据库。
相比于轮询SQL缓存依赖,使用推依赖的好处是ASP.NET应用程序不必定时地轮询数据库的修改。如果有修改,数据库会通知应用程序。
也有不太好的一面,使用推依赖的查询类型有诸多限制。下面是比较显著的一些限制。
l 查询必须使用两部分的表名(例如,dbo.Movies而不是Movies)。
l 查询必须包含一个显式的列名列表(不能使用*)。
l 查询不能引用视图、继承表、临时表或表变量。
l 查询不能引用大对象类型,如Text、NText和Image列。
l 查询不能包含子查询、外联结或子联结。
l 查询不能使用DISTINCT、COMPUTE、COMPUTE BY或者INSERT关键字。
l 查询不能使用许多聚合函数,包括AVG、COUNT(*)、MAX和MIN。
这里只是一个不完整的查询限制的列表。要查看完整的列表,可以参考SQL Server 2005在线图书或MSDN网站(msdn.microsoft.com)的“创建一个通知查询”的主题。
例如,下面这个简单的查询不能工作:
SELECT * FROM Movies
该查询不能工作有两个原因。第一是不能使用星号(*)来代表列,第二是必须使用两部分的表名。而下面这个查询就能工作:
SELECT Title,Director FROM dbo.Movies
可以对推SQL缓存依赖使用存储过程。不过,每一个存储过程中的SELECT语句必须满足刚才列出的限制列表。
4.6.7 配置推SQL缓存依赖
要启用推SQL缓存依赖,必须完成下面两步配置。
l 必须配置数据库启用SQL Server 2005 Service Broker。
l 必须配置应用程序开始监听通知。
在这一小节,你将了解到如何完成这两个配置步骤。
注意 遗憾的是,当推缓存依赖失败时,不会有任何错误报告发送到事件日志。这就使得调试变得极其困难。我建议,完成这一小节讨论的配置修改后,重新启动Web服务器和数据库服务器。
1. 为推SQL缓存依赖配置数据库
在使用推SQL缓存依赖之前,必须启用Microsoft SQL Server 2005 Service Broker。可以执行下面的SQL查询来检查Service Broker是否已经为特定的数据库激活:
SELECT name, is_broker_enabled FROM sys.databases
如果Service Broker还没有启用,则要执行ALTER DATABASE命令来启用它。例如,下面的SQL命令为MyMovies数据库启用了Service Broker:
ALTER DATABASE MyMovies SET ENABLE_BROKER
最后,ASP.NET进程必须有足够的权限来订阅查询通知。当一个ASP.NET页面由IIS处理时,页面在NT Authority WET WORK SERVICE账号(对于Windows Server 2003或Vista)或者ASPNET账号(对于其他操作系统,如Windows XP)上下文中执行。
执行下面的SQL命令能给YOURSERVER服务器上的本地ASPNET账号赋予需要的权限:
GRANT SUBSCRIBE QUERY NOTIFICATIONS TO "YOURSERVER\ASPNET"
当使用Visual Web Developer的Web服务器来请求一个ASP.NET页面时,ASP.NET页面在当前用户账号的安全上下文中执行。因此,当使用文件系统网站时,需要对当前账号执行SUBSCRIBE QUERY NOTIFICATIONS来授权。
注解 推SQL缓存依赖并不使用SQL Server 2005的通知服务。
2. 为推SQL缓存依赖配置应用程序
在应用程序可以接收到变更通知之前,必须启用查询通知监听器。可以在如代码清单4-45所示的Global.asax文件中启用监听器。
代码清单4-45 Global.asax
<%@ Application Language=”C#” %>
<%@ Import Namespace=”System.Data.SqlClient” %>
<%@ Import Namespace=”System.Web.Configuration” %>
<script runat=”server”>
void Application_Start(object sender, EventArgs e)
{
// Enable Push SQL cache dependencies
string conString = WebConfigurationManager.ConnectionStrings
➥["MyMovies"].ConnectionString;
SqlDependency.Start(conString);
}
</script>
Application_Start事件处理程序只在应用程序刚开始运行时执行一次。在代码清单4-45中,SqlDependency.Start()方法使用一个指向SQL Express的MyMovies服务器数据库的连接字符串调用。
注意 代码清单4-45中的代码在随书附带资源中的Global.asa文件中被注释了,这样它就不会影响本章前面讨论的所有代码。接下来,去掉注释并使用示例代码。
4.6.8 对页面输出缓存使用推SQL缓存依赖
当缓存整个ASP.NET页面时,可以使用推SQL缓存依赖。如果包含在页面上的任何SQL命令的结果有改变,页面就会自动从缓存中删除。
SqlCommand对象包含一个NotificationAutoEnlist属性,该属性默认值为true。当Notification- AutoEnlist启用时,页面和命令之间会自动创建一个推缓存依赖。
例如,代码清单4-46所示的页面包含<%@ OUtputCache %>指令,其中SqlDependency特性的值为CommandNotification。
代码清单4-46 PushSQLOutputCache.aspx
<%@ Page Language="C#" %>
<%@ OutputCache Duration="9999" VaryByParam="none"
SqlDependency="CommandNotification" %>
<!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 id="Head1" runat="server">
<title>Push SQL Output Cache</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<%= DateTime.Now.ToString("T") %>
<hr />
<asp:GridView
id="grdMovies"
DataSourceID="srcMovies"
Runat="server" />
<asp:SqlDataSource
id="srcMovies"
ConnectionString="<%$ ConnectionStrings:MyMovies %>"
SelectCommand="SELECT Title, Director FROM dbo.Movies"
Runat="server" />
</div>
</form>
</body>
</html>
代码清单4-46所示的页面包含一个SqlDataSource控件,可以从Movies数据库表获取所有记录。注意,SqlDataSource控件使用了显式列名的SQL查询,并使用了两部分格式表名。这些都是使用推缓存依赖必需的。
代码清单4-46所示的页面显示了当前时间。如果从浏览器请求该页面并刷新页面,时间不会变化。只有修改Movies数据表时,时间才会变。
注意 代码清单4-46所示的页面连接到一个名为MyMovies的服务器数据库。不要对本地SQL Express数据库使用推依赖。该页面使用一个Movies数据库表,创建这个表的SQL命令如下:
CREATE TABLE Movies
(
Id int IDENTITY NOT NULL,
Title nvarchar(100) NOT NULL,
Director nvarchar(50) NOT NULL,
EntryDate datetime NOT NULL DEFAULT GetDate()
)
注意 不能对包含<%@ OutputCache %>指令的用户控件使用推SQL缓存依赖。也就是说,不能对部分页面缓存使用推SQL缓存依赖。
4.6.9 对数据源缓存使用推SQL缓存依赖
也可以对SqlDataSource和ObjectDataSource使用推SQL缓存依赖,只需设置SqlCacheDependency属性即可。不同于轮询依赖,使用推依赖需要设置SqlCacheDependency属性为CommandNotification。
例如,代码清单4-47所示的页面包含了一个SqlDataSource控件,设置了EnableCaching和SqlDependency属性集。
代码清单4-47 PushSQLDataSourceCache.aspx
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void srcMovies_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
lblMessage.Text = "Retrieving data from database";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Push SQL DataSource Cache</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label
id="lblMessage"
EnableViewState="false"
Runat="server" />
<hr />
<asp:GridView
id="grdMovies"
DataSourceID="srcMovies"
Runat="server" />
<asp:SqlDataSource
id="srcMovies"
ConnectionString="<%$ ConnectionStrings:MyMovies %>"
SelectCommand="SELECT Title, Director FROM dbo.Movies"
EnableCaching="true"
SqlCacheDependency="CommandNotification"
OnSelecting="srcMovies_Selecting"
Runat="server" />
</div>
</form>
</body>
</html>
在代码清单4-47中,SqlDataSource控件包括一个Selecting事件处理程序。因为该事件在数据不能从缓存中获得时触发,所以可以用它来判断数据从缓存中返回还是从数据库服务器中返回(见图4-17)。
图4-17 对DataSource控件使用推SQL缓存依赖
注意 代码清单4-47所示的页面连接到一个名为MyMovies的服务器数据库。不要对本地SQL Express数据库使用推依赖。该页面使用一个Movies数据库表,创建这个表的SQL命令如下:
CREATE TABLE Movies
(
Id int IDENTITY NOT NULL,
Title nvarchar(100) NOT NULL,
Director nvarchar(50) NOT NULL,
EntryDate datetime NOT NULL DEFAULT GetDate()
)
4.6.10 对数据缓存使用推SQL缓存依赖
也可以对Cache对象使用推SQL缓存依赖。可以用一个SqlCacheDependency类的实例代表一个推SQL缓存依赖。
例如,在代码清单4-48所示的Page_Load()事件处理程序中,一个DataTable添加到缓存,它代表了Movies数据库表的内容。这个DataTable显示在一个GridView控件中。
代码清单4-48 PushSQLDataCache.aspx
<%@ Page Language="C#" Trace="true" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Web.Configuration" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void Page_Load()
{
DataTable movies = (DataTable)Cache["Movies"];
if (movies == null)
{
Trace.Warn("Retrieving data from database");
string conString = WebConfigurationManager.ConnectionStrings["MyMovies"].ConnectionString;
SqlDataAdapter dad = new SqlDataAdapter("SELECT Title,Director FROM dbo.Movies", conString);
SqlCacheDependency sqlDepend = new SqlCacheDependency(dad.SelectCommand);
movies = new DataTable();
dad.Fill(movies);
Cache.Insert("Movies", movies, sqlDepend);
}
grdMovies.DataSource = movies;
grdMovies.DataBind();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Push SQL Data Cache</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView
id="grdMovies"
Runat="server" />
</div>
</form>
</body>
</html>
注意,SqlCacheDependency类的实例被创建了。一个SqlCommand对象被传递给了SqlCacheDependency类的构造函数。如果SqlCommand的结果变化了,则这个DataTable会自动从缓存中删除。
这些命令的顺序很重要。必须在执行该命令之前创建SqlCacheDependency对象。如果在创建SqlCacheDependency对象之前调用Fill()方法,则依赖会被忽略。
注意 代码清单4-48所示的页面连接到一个名为MyMovies的服务器数据库。不要对本地SQL Express数据库使用推依赖。该页面使用一个Movies数据库表,创建这个表的SQL命令如下:
CREATE TABLE Movies
(
Id int IDENTITY NOT NULL,
Title nvarchar(100) NOT NULL,
Director nvarchar(50) NOT NULL,
EntryDate datetime NOT NULL DEFAULT GetDate()
)
本文来自租赁宝网技术支持,参考网站:http://www.zulinbao.com