开发者社区> 老朱教授> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

再谈ASP.NET 2.0 中的缓存功能

简介:
+关注继续查看

数据库缓存
在处理数据库数据时,通常使用下列三个 DataSource 控件中的一个控件: 
   • SqlDataSource — 表示 SQL 数据源,例如 Microsoft SQL Server 或 Oracle 数据库。 
   • AccessDataSource — 一个专用的 SqlDataSource 控件,用于 Microsoft Access 数据库。 
   • ObjectDataSource — 表示充当数据源的自定义业务对象。
例如,假设您要在 DropDownList 控件中显示从数据库中检索到的书目列表(下图)。列表 1 中的页面说明了如何将 DropDownList 控件绑定到 SqlDataSource 控件。
None.gif <html> 
None.gif  
<head runat="server"> 
None.gif  
<title>Display Titles</title> 
None.gif  
</head> 
None.gif  
<body> 
None.gif  
<form id="form1" runat="server"> 
None.gif   
None.gif  
<asp:DropDownList 
None.gif  
ID="DropDownList1" 
None.gif  DataSourceId
="SqlDataSource1" 
None.gif  DataTextField
="Title" 
None.gif  Runat
="server" /> 
None.gif   
None.gif  
<asp:SqlDataSource 
None.gif  
ID="SqlDataSource1" 
None.gif  ConnectionString
="Server=localhost;database=Pubs" 
None.gif  SelectCommand
="SELECT Title FROM Titles" 
None.gif  Runat
="server" /> 
None.gif   
None.gif  
</form> 
None.gif  
</body> 
None.gif  
</html>
在上图SqlDataSource 控件用于提供连接字符串,SQL SELECT 命令用于从数据库中检索记录。DropDownList 控件通过其 DataSourceID 属性绑定到 SqlDataSource 控件。 
   使用 DataSource 控件缓存数据 
  使用 DataSource 控件,不仅可以更轻松地连接数据库,还使缓存数据库数据变得更容易。只需在 SqlDataSource 控件上设置一两个属性,就可以自动在内存中缓存由 DataSource 控件表示的数据。 
   例如,如果要将 Titles 数据库表在内存中缓存至少 10 分钟,可以按照以下方式声明 SqlDataSource 控件。 
   <asp:SqlDataSource 
  ID="SqlDataSource1" 
  EnableCaching="true" 
  CacheDuration="600" 
  ConnectionString="Server=localhost;database=Pubs" 
  SelectCommand="SELECT Title FROM Titles" 
  Runat="server" /> 
    如果 EnableCaching 属性的值为 true,SqlDataSource 将自动缓存通过 SelectCommand 检索到的数据。使用 CacheDuration 属性,可以指定从数据库中刷新数据之前缓存数据的时间(以秒为单位)。 
   默认情况下,SqlDataSource 使用绝对过期策略来缓存数据,即每隔指定的秒数就从数据库中刷新一次。此外,您还可以选择使用可变过期策略。如果将 SqlDataSource 配置为使用可变过期策略,那么只要持续访问数据,数据就不会过期。如果需要缓存大量项目,使用可变过期策略将非常有用,因为这种过期策略将只在内存中保留访问最频繁的项目。 
   例如,下面的 SqlDataSourceControl 被配置为使用可变过期策略,过期时间为 10 分钟。  
  <asp:SqlDataSource 
  ID="SqlDataSource1" 
  EnableCaching="true" 
  CacheExpirationPolicy="Sliding" 
  CacheDuration="600" 
  ConnectionString="Server=localhost;database=Pubs" 
  SelectCommand="SELECT Title FROM Titles" 
  Runat="server" /> 
   由于 CacheExpirationPolicy 属性的值被设置为 Sliding,CacheDuration 属性的值被设置为 600,因此,只要在 10 分钟内持续访问,此 SqlDataSource 表示的数据就会一直保留在内存中。 
   
 
  使用 SQL Cache Invalidation 
  SQL Cache Invalidation 是 ASP.NET 2.0 Framework 最值得期待的新增功能之一。使用 SQL Cache Invalidation 可以获得缓存的全部性能优势,而不用担心数据过期的问题。SQL Cache Invalidation 使您可以在基础数据库中的数据发生更改时自动更新缓存中的数据。 
   SQL Cache Invalidation 通过在后台不断轮询数据库来检查数据更改。每隔一定的时间(毫秒),ASP.NET Framework 就会检查数据库中是否存在更新。如果 ASP.NET Framework 检测到任何更改,将从缓存中删除从数据库中添加的、依赖于数据库的任何项目(即,这些项目将过期)。 
     注意:Microsoft SQL Server 2005 支持一种截然不同的 SQL Cache Invalidation 方法。您可以配置 SQL Server 2005,使其在数据库、数据库表或数据库行发生变化时通知 ASP.NET 应用程序。这样,ASP.NET Framework 就不需要通过不断轮询 SQL Server 2005 数据库来检查数据更改了。 
   需要注意的是,SQL Cache Invalidation 只能用于 Microsoft SQL Server 7 及更高版本,不能用于其他数据库,例如 Microsoft Access 或 Oracle。 
    在缓存整个页面的输出、使用 DataSource控件或直接使用 Cache 对象时,都可以使用 SQL Cache Invalidation。下面将分别介绍这三种情况。 
   
  配置 SQL Cache Invalidation 
  在 Web 应用程序中使用 SQL Cache Invalidation 之前,首先必须执行一些配置步骤。必须将 Microsoft SQL Server 配置为支持 SQL Cache Invalidation,还必须在应用程序的 Web 配置文件中添加必要的配置信息。 
   可以按照以下两种方法配置 SQL Server:使用 aspnet_regsql 命令行工具,或者使用 SqlCacheDependencyAdmin 类。 
   使用 ASPNET_REQSQL 启用 SQL Cache Invalidation 
  使用 aspnet_regsql 工具,您可以通过命令行来配置 SQL Cache Invalidation。aspnet_regsql 工具位于 Windows\Microsoft.NET\Framework\[版本] 文件夹中。要使用此工具,必须打开命令提示符窗口并浏览到此文件夹。 
   要在使用 Pubs 数据库时支持 SQL Cache Invalidation,需要执行以下命令。 
   aspnet_regsql -E -d Pubs -ed 
   -E 选项使 aspnet_regsql 工具在连接到数据库服务器时使用集成的安全设置。-d 选项用于选择 Pubs 数据库。最后,-ed 选项用于为数据库启用 SQL Cache Invalidation。 
   执行此命令时,将在数据库中添加一个名为 AspNet_SqlCacheTablesForChangeNotification 的新数据库表。此表包含启用了 SQL Cache Invalidation 的所有数据库表的列表。此命令还将在数据库中添加一组存储过程。 
   为数据库启用 SQL Cache Invalidation 后,必须从数据库中选择要启用 SQL Cache Invalidation 的特定表。以下命令将为 Titles 数据库表启用 SQL Cache Invalidation。 
   aspnet_regsql -E -d Pubs -t Titles -et 
    -t 选项用于选择数据库表。-et 选项为数据库表启用 SQL Cache Invalidation。当然,您可以通过对每个数据库表重复执行此命令,为多个表启用 SQL Cache Invalidation。 
   执行此命令时,将在数据库表中添加一个触发器。只要您对表进行了修改,此触发器就将触发并更新 AspNet_SqlCacheTablesForChangeNotification 表。 
   最后,要获取某个特定数据库中当前启用了 SQL Cache Invalidation 的表的列表,可以使用以下命令。 
   aspnet_regsql -E -d Pubs -lt 
    此方法将从 AspNet_SqlCacheTablesForChangeNotification 中选择表的列表。此外,您也可以通过直接在该数据库表中执行查询来检索此信息。 
    使用 SqlCacheDependencyAdmin 类 
  aspnet_regsql 工具在后台使用 SqlCacheDependencyAdmin 类的方法来配置 Microsoft SQL Server。如果您愿意,可以直接从 ASP.NET 页面中使用此类的方法。 
   SqlCacheDependencyAdmin 类具有五个重要的方法: 
   • DisableNotifications — 为特定数据库禁用 SQL Cache Invalidation。 
    • DisableTableForNotifications — 为数据库中的特定表禁用 SQL Cache Invalidation。 
    • EnableNotifications — 为特定数据库启用 SQL Cache Invalidation。 
    • EnableTableForNotifications — 为数据库中的特定表启用 SQL Cache Invalidation。 
   • GetTablesEnabledForNotifications — 返回启用了 SQL Cache Invalidation 的所有表的列表。 
    例如,使用列表 2 中的 ASP.NET 页面,您可以为 Pubs 数据库中的任何表配置 SQL Cache Invalidation(下图)。 
ExpandedBlockStart.gif<%@ Page Language="c#" %> 
ExpandedBlockStart.gif  
<%@ Import Namespace="System.Web.Caching" %> 
ExpandedBlockStart.gif  
<script runat="server"> 
InBlock.gif   
InBlock.gif  const string connectionString 
= "Server=localhost;Database=Pubs"
InBlock.gif   
InBlock.gif  
void Page_Load() 
ExpandedSubBlockStart.gif   

InBlock.gif  
if (!IsPostBack) 
ExpandedSubBlockStart.gif   

InBlock.gif  SqlCacheDependencyAdmin.EnableNotifications( 
InBlock.gif  connectionString); 
InBlock.gif  SqlDataSource1.SelectParameters.Add(
"connectionString"
InBlock.gif  connectionString); 
ExpandedSubBlockEnd.gif   }
 
ExpandedSubBlockEnd.gif   }
 
InBlock.gif   
InBlock.gif  
void EnableTable(Object s, EventArgs e) 
ExpandedSubBlockStart.gif   

InBlock.gif  
try 
ExpandedSubBlockStart.gif   

InBlock.gif  SqlCacheDependencyAdmin.EnableTableForNotifications( 
InBlock.gif  connectionString, txtTableName.Text); 
ExpandedSubBlockEnd.gif   }
 
InBlock.gif  
catch (Exception ex) 
ExpandedSubBlockStart.gif   

InBlock.gif  lblErrorMessage.Text 
= ex.Message; 
ExpandedSubBlockEnd.gif   }
 
InBlock.gif  txtTableName.Text 
= ""
ExpandedSubBlockEnd.gif   }
 
InBlock.gif   
ExpandedBlockEnd.gif  
</script> 
None.gif   
None.gif  
<html> 
None.gif  
<head runat="server"> 
None.gif  
<title>Enable SQL Cache Invalidation</title> 
None.gif  
</head> 
None.gif  
<body> 
None.gif  
<form id="form1" runat="server"> 
None.gif   
None.gif  
<h1>SQL Cache Invalidation</h1> 
None.gif   
None.gif  以下表格已启用 SQL Cache Invalidation: 
None.gif   
None.gif  
<p> 
None.gif  
<asp:GridView id="grdTables" 
None.gif  DataSourceID
="SqlDataSource1" CellPadding="10" 
None.gif  ShowHeader
="false" Runat="Server" /> 
None.gif  
</p> 
None.gif   
None.gif  
<asp:ObjectDataSource 
None.gif  
ID="SqlDataSource1" 
None.gif  TypeName
="System.Web.Caching.SqlCacheDependencyAdmin" 
None.gif  SelectMethod
="GetTablesEnabledForNotifications" 
None.gif  Runat
="Server" /> 
None.gif  
<p> 
None.gif  
<asp:Label ID="lblErrorMessage" EnableViewState="false" 
None.gif  ForeColor
="red" Runat="Server" /> 
None.gif  
</p> 
None.gif   
None.gif  
<asp:TextBox ID="txtTableName" Runat="Server" /> 
None.gif  
<asp:Button Text="Enable Table" OnClick="EnableTable" 
None.gif  Runat
="Server" /> 
None.gif   
None.gif  
</form> 
None.gif  
</body> 
None.gif  
</html> 
connectionString 常量用于选择启用了 SQL Cache Invalidation 的数据库(如果要为 Pubs 数据库以外的数据库启用 SQL Cache Invalidation,可以更改此常量的值)。在 Page_Load 方法中,调用 SqlCacheDependencyAdmin 类上的 EnableNotifications 方法,为由 connectionString 常量指定的数据库启用 SQL Cache Invalidation。 
   
  列表 2 中的 GridView 显示了当前启用了 SQL Cache Invalidation 的所有数据库表。GridView 被绑定到 ObjectDataSource 控件上,该控件为其 SelectMethod 调用 GetTablesneabledForNotifications 方法。 
   
  最后,您可以使用列表 2 中的页面为其他表启用 SQL Cache Invalidation。在文本框中输入表的名称并单击“Enable Table”按钮时,将调用 EnableTableForNotifications 方法。 
    SQL Cache Invalidation 的 Web 配置设置 
  在 ASP.NET 应用程序中使用 SQL Cache Invalidation 之前,下一步要做的是更新您的 Web 配置文件。您需要配置 ASP.NET Framework,以便轮询启用了 SQL Cache Invalidation 的数据库。 
Web 配置文件包含轮询 Pubs 数据库所必需的配置信息。Web.Config 
None.gif <configuration> 
None.gif   
None.gif  
<connectionStrings> 
None.gif  
<add name="mySqlServer" 
None.gif  connectionString
="Server=localhost;Database=Pubs" /> 
None.gif  
</connectionStrings> 
None.gif   
None.gif  
<system.web> 
None.gif   
None.gif  
<caching> 
None.gif  
<sqlCacheDependency enabled="true"> 
None.gif  
<databases> 
None.gif  
<add 
None.gif  
name="Pubs" 
None.gif  connectionStringName
="mySqlServer" 
None.gif  pollTime
="60000" /> 
None.gif  
</databases> 
None.gif  
</sqlCacheDependency> 
None.gif  
</caching> 
None.gif  
</system.web> 
None.gif  
</configuration> 
Web 配置文件包含两部分。<connectionStrings> 部分用于创建数据库连接字符串,以连接到名为 mySqlServer 的 Pubs 数据库。 
   caching 部分用于配置 SQL Cache Invalidation 轮询。在 <databases> 子部分中,您可以列出要对其进行轮询以检查数据更改的一个或多个数据库。在列表 3 中,mySqlServer 表示的数据库每分钟(每 60000 毫秒)轮询一次。 
    您可以为不同的数据库指定不同的轮询间隔。每次轮询数据库以检查数据更改时,服务器都必须执行一些操作。如果您认为数据库中的数据不会频繁地更改,可以增加轮询间隔。 
   在页面输出缓存中使用 SQL Cache Invalidation 
  现在,我们已经完成了 SQL Cache Invalidation 的所有配置步骤,可以在 ASP.NET 页面中使用它了。一种方法是在页面输出缓存中使用 SQL Cache Invalidation。页面输出缓存允许您在内存中缓存页面所显示的所有内容。通过使用 SQL Cache Invalidation,您可以在(且只在)数据库表发生更改时自动更新缓存的页面。 
下面页面在 GridView 控件中显示了 Titles 数据库表的内容。在该页面的顶部,OutputCache 指令用于在内存中缓存页面内容。如果 Titles 数据库表发生更改,SqlDependency 属性将使页面更新。 
ExpandedBlockStart.gif<%@ OutputCache SqlDependency="Pubs:Titles" 
ExpandedBlockEnd.gif  Duration
="6000" VaryByParam="none" 
%> 
None.gif  
<html> 
None.gif  
<head runat="server"> 
None.gif  
<title>Output Cache Titles</title> 
None.gif  
</head> 
None.gif  
<body> 
None.gif  
<form id="form1" runat="server"> 
None.gif   
None.gif  
<%= DateTime.Now %> 
None.gif   
None.gif  
<asp:GridView 
None.gif  
ID="grdTitles" 
None.gif  DataSourceID
="SqlDataSource1" 
None.gif  Runat
="Server" /> 
None.gif   
None.gif  
<asp:SqlDataSource 
None.gif  
ID="SqlDataSource1" 
None.gif  SelectCommand
="Select * FROM Titles" 
None.gif  ConnectionString
="<%$ ConnectionStrings:mySqlServer %>" 
None.gif  Runat
="Server" /> 
None.gif   
None.gif  
</form> 
None.gif  
</body> 
None.gif  
</html>

请注意,SqlDependency 属性引用了 Web 配置文件中定义的数据库的名称。由于我们指定了每分钟轮询一次 Pubs 数据库以检查数据更改,因此如果对该数据库进行了更改,列表 4 中的页面将在一分钟之内进行更新。 
   
  您可以为 SqlDependency 属性值列出多个数据库和/或多个数据库表。要创建多个依赖关系,只需用分号分隔每个依赖关系即可。 
   
  在 DataSource 控件中使用 SQL Cache Invalidation 
  除了在页面输出缓存中使用 SQL Cache Invalidation 之外,还可以直接在 DataSource 控件中使用 SQL Cache Invalidation。如果要在多个页面中使用相同的数据库数据,请考虑在 DataSource 控件中使用 SQL Cache Invalidation。SqlDataSource、AccessDataSource 和 ObjectDataSource 控件都支持 SqlCacheDependency 属性。 
下面页面在 SqlDataSource 控件中使用了 SQL Cache Invalidation

None.gif<html> 
None.gif  
<head id="Head1" runat="server"> 
None.gif  
<title>SqlDataSource Caching</title> 
None.gif  
</head> 
None.gif  
<body> 
None.gif  
<form id="form1" runat="server"> 
None.gif   
None.gif  
<%= DateTime.Now %> 
None.gif   
None.gif  
<asp:GridView 
None.gif  
ID="grdTitles" 
None.gif  DataSourceId
="SqlDataSource1" 
None.gif  Runat
="server" /> 
None.gif   
None.gif  
<asp:SqlDataSource 
None.gif  
ID="SqlDataSource1" 
None.gif  EnableCaching
="true" 
None.gif  SqlCacheDependency
="Pubs:Titles" 
None.gif  SelectCommand
="select * from titles" 
None.gif  ConnectionString
="<%$ ConnectionStrings:mySqlServer %>" 
None.gif  Runat
="server" /> 
None.gif   
None.gif  
</form> 
None.gif  
</body> 
None.gif  
</html>

SqlDataSource 控件是使用 EnableCaching 和 SqlCacheDependency 这两个属性声明的。SqlCacheDependency 属性使用的语法与 OutputCache 指令的 SqlDependency 属性相同。您需要列出数据库的名称,后跟数据库表的名称。 
   
  在 Cache 对象中使用 SQL Cache Invalidation 
  最后,您还可以在 Cache 对象中使用 SQL Cache Invalidation。此选项使您可以最大程度地对 SQL Cache Invalidation 进行编程控制。 
   
  要在 Cache 对象中使用 SQL Cache Invalidation,您需要创建一个 SqlCacheDependency 对象实例。使用 Insert 方法在 Cache 中插入新对象时,可以使用 SqlCacheDependency 对象。 
下面页面显示了 Titles 数据库表中的记录数。计数是基于对基础数据库表的依赖关系进行缓存的。 

ExpandedBlockStart.gif <%@ Page Language="c#" %> 
ExpandedBlockStart.gif  
<%@ Import Namespace="System.Data.SqlClient" %> 
ExpandedBlockStart.gif  
<script runat="server"> 
InBlock.gif   
InBlock.gif  
void Page_Load() 
ExpandedSubBlockStart.gif   

InBlock.gif  
int count = 0
InBlock.gif   
InBlock.gif  
if (Cache["TitleCount"!= null
ExpandedSubBlockStart.gif   

InBlock.gif  count 
= (int)Cache["TitleCount"]; 
ExpandedSubBlockEnd.gif   }
 
InBlock.gif  
else 
ExpandedSubBlockStart.gif   

InBlock.gif  string connectionString 
= 
InBlock.gif  ConfigurationSettings.ConnectionStrings[ 
InBlock.gif  
"mySqlServer"].ConnectionString; 
InBlock.gif  SqlConnection con 
= new SqlConnection(connectionString); 
InBlock.gif  SqlCommand cmd 
= new 
InBlock.gif  SqlCommand(
"SELECT Count(*) FROM Titles", con); 
InBlock.gif  con.Open(); 
InBlock.gif  count 
= (int)cmd.ExecuteScalar(); 
InBlock.gif  con.Close(); 
InBlock.gif  Cache.Insert(
"TitleCount", count, 
InBlock.gif  
new SqlCacheDependency("Pubs""Titles")); 
ExpandedSubBlockEnd.gif   }
 
InBlock.gif  lblTitleCount.Text 
= count.ToString(); 
ExpandedSubBlockEnd.gif   }
 
InBlock.gif   
ExpandedBlockEnd.gif  
</script> 
None.gif   
None.gif  
<html> 
None.gif  
<head runat="server"> 
None.gif  
<title>Display Title Count</title> 
None.gif  
</head> 
None.gif  
<body> 
None.gif  
<form id="form1" runat="server"> 
None.gif   
None.gif  
<asp:Label ID="lblTitleCount" Runat="Server" /> 
None.gif   
None.gif  
</form> 
None.gif  
</body> 
None.gif  
</html> 

使用 Post-Cache Substitution 
  在许多情况下,您需要缓存页面的一部分,而不是整个页面。例如,在您的 Web 站点主页上,您可能希望同时显示随机的标题广告和数据库表中的记录。如果缓存整个页面,每个用户都将在每次请求的页面上看到同一个标题广告。 
   
  要处理这种同时混有动态内容和缓存内容的问题,一种方法是使用 Web 用户控件。因为可以为 Web 用户控件添加 OutputCache 指令,所以即使不缓存包含页面的内容,也可以缓存 Web 用户控件的内容。 
   
  但有时候可能会事与愿违。虽然您可以使用 Web 用户控件在动态页面上添加缓存的内容,但很多情况下,您实际上是想在缓存的页面中添加动态内容。例如,假设您要缓存整个页面的内容,只留一小块区域用于显示当前用户的用户名。这种情况下最好使用 Post-Cache Substitution。 
   
  ASP.NET 2.0 Framework 引入了一种新控件,称为 Substitution 控件。您可以使用 Substitution 控件在缓存的页面中插入动态内容。

ExpandedBlockStart.gif<%@ Page Language="C#" %> 
ExpandedBlockStart.gif  
<%@ OutputCache Duration="6000" VaryByParam="none" %> 
None.gif   
ExpandedBlockStart.gif  
<script runat="server"> 
InBlock.gif   
InBlock.gif  static string DisplayUsername(HttpContext context) 
ExpandedSubBlockStart.gif   

InBlock.gif  
if (!context.Request.IsAuthenticated) 
InBlock.gif  
return "Anonymous"
InBlock.gif  
else 
InBlock.gif  
return context.User.Identity.Name; 
ExpandedSubBlockEnd.gif   }
 
InBlock.gif   
ExpandedBlockEnd.gif  
</script> 
None.gif   
None.gif  
<html> 
None.gif  
<head runat="server"> 
None.gif  
<title>Post Cache Substitution</title> 
None.gif  
</head> 
None.gif  
<body> 
None.gif  
<form id="form1" runat="server"> 
None.gif   
None.gif  Welcome 
<asp:Substitution 
None.gif  
MethodName="DisplayUsername" Runat="Server" />
None.gif   
None.gif  
<p> 
None.gif  此页已缓存, 因为时间 
None.gif  
<%= DateTime.Now.ToString("t"%> 并无改变。 
None.gif  
</p> 
None.gif   
None.gif  
</form> 
None.gif  
</body> 
None.gif  
</html>

 Substitution 控件有一个非常重要的属性:即 MethodName 属性。MethodName 属性用于表示为返回动态内容而调用的方法。由 Substitution 控件调用的方法必须是静态方法(在 Visual Basic .NET 中共享的方法)。此外,该方法还必须具有一个表示当前 HttpContext 的参数。 
   
  在 ASP.NET 2.0 Framework 中,已对 AdRotator 控件进行了修改以支持 Post-Cache Substitution。如果在使用 OutputCache 指令的页面中添加 AdRotator 控件,AdRotator 控件将自动从其包含页面的缓存策略中排除出去。 




本文转自高海东博客园博客,原文链接:http://www.cnblogs.com/ghd258/archive/2005/10/27/263019.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
云时代开发者能力模型与提升之道
立即下载
AGit-flow:新一代高效Git协同模型
立即下载
低代码开发师(初级)实战教程
立即下载