引言
除了在页面或用户控件级别进行缓存外,也可以在数据源控件层面进行缓存。所有三个标准的数据源控件——SqlDataSource、ObjectDataSource和XmlDataSource控件都包含了用于缓存DataSource承载的数据属性。
使用绝对缓存过期策略
Code
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>DataSource Absolute Cache</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView
id="grdMovies"
DataSourceID="srcMovies"
Runat="server" />
<asp:SqlDataSource
id="srcMovies"
EnableCaching="True"
CacheDuration="3600"
SelectCommand="SELECT * FROM Movies"
ConnectionString="<%$ ConnectionStrings:Movies %>"
Runat="server" />
</div>
</form>
</body>
</html>
使用Sliding缓存过期策略
如果需要缓存大量数据,则使用sliding过期策略比绝对缓存过期要更合理。当使用sliding缓存过期策划时,除非数据在指定时间内再次被请求,否则缓存就会失效。
Code
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<script runat="server">
protected void srcMovies_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
lblMessage.Text = "Selecting data from database";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>DataSource Sliding Cache</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<p>
<asp:Label
id="lblMessage"
EnableViewState="false"
Runat="server" />
</p>
<asp:GridView
id="grdMovies"
DataSourceID="srcMovies"
Runat="server" />
<asp:SqlDataSource
id="srcMovies"
EnableCaching="True"
CacheExpirationPolicy="Sliding"
CacheDuration="15"
SelectCommand="SELECT * FROM Movies"
ConnectionString="<%$ ConnectionStrings:Movies %>"
OnSelecting="srcMovies_Selecting"
Runat="server" />
</div>
</form>
</body>
</html>
使用ObjectDataSource控件缓存
ObjectDataSource控件支持和SqlDataSource控件一样的缓存属性。可以通过设置ObjectDataSource的EnableCaching、CacheDuration和CacheExpirationPolicy(可选)属性来缓存数据。
Code
<%@ 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, ObjectDataSourceSelectingEventArgs e)
{
lblMessage.Text = "Selecting data from component";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Show ObjectDataSource Caching</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label
id="lblMessage"
EnableViewState="false"
Runat="server" />
<br /><br />
<asp:GridView
id="grdMovies"
DataSourceID="srcMovies"
Runat="server" />
<asp:ObjectDataSource
id="srcMovies"
EnableCaching="true"
CacheDuration="15"
TypeName="Movie"
SelectMethod="GetMovies"
OnSelecting="srcMovies_Selecting"
Runat="server" />
</div>
</form>
</body>
</html>
上面代码中ObjectDataSource控件包含一个Selecting事件的事件处理函数。该事件处理函数在一个Label控件显示一个消息。因为Selecting事件在数据从缓存中取得的是不触发的,可以用该事件来判断数据是从缓存还是从Movie组件获得的。
Code
1 using System;
2 using System.Data;
3 using System.Data.SqlClient;
4 using System.Web.Configuration;
5
6 public class Movie
7 {
8 public static DataTable GetMovies()
9 {
10 string conString = WebConfigurationManager.ConnectionStrings["Movies"].ConnectionString;
11 SqlDataAdapter dad = new SqlDataAdapter("SELECT Title,Director FROM Movies", conString);
12 DataTable movies = new DataTable();
13 dad.Fill(movies);
14 return movies;
15 }
16 }
使用XmlDataSource控件缓存
该控件默认启用缓存,并且自动和承载它的数据的XML文件创建一个文件依赖。XML文件修改,则该控件自动重新载入修改过的XML文件。
Code
<%@ Page Language="C#" %>
<!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>Show XmlDataSource Caching</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView
id="grdMovies"
DataSourceID="srcMovies"
Runat="server" />
<asp:XmlDataSource
id="srcMovies"
DataFile="Movies.xml"
Runat="server" />
</div>
</form>
</body>
</html>
创建数据源控件键值依赖
可以在数据源控件和应用程序的一个缓存项目之间建立一个键值依赖。这样修改数据后删除了该缓存项目,对应的数据源控件会自动载入修改后的数据。
Code
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<script runat="server">
protected void srcMovies_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
lblMessage.Text = "Selecting data from database";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>DataSource Key Dependency</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<p>
<asp:Label
id="lblMessage"
EnableViewState="false"
Runat="server" />
</p>
<asp:GridView
id="grdMovies"
DataSourceID="srcMovies"
Runat="server" />
<asp:SqlDataSource
id="srcMovies"
EnableCaching="True"
CacheDuration="Infinite"
CacheKeyDependency="MovieKey"
SelectCommand="SELECT * FROM Movies"
ConnectionString="<%$ ConnectionStrings:Movies %>"
OnSelecting="srcMovies_Selecting"
Runat="server" />
<br /><br />
<a href="AddMovieDataSourceKeyDependency.aspx">Add Movie</a>
</div>
</form>
</body>
</html>
注意上面的代码清单中的SqlDataSource控件包含了一个CacheKeyDependency属性,值为Moviekey。该属性在数据源控件缓存的数据和名为Moviekey的缓存项目之间建立了一个依赖。
下面所示的Global.asax创建了初始化的Moviekey缓存项目。
Code
<%@ Application Language="C#" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Web.Configuration" %>
<script runat="server">
public override string GetVaryByCustomString(HttpContext context, string custom)
{
if (String.Compare(custom, "css") == 0)
{
return Request.Browser.SupportsCss.ToString();
}
return base.GetVaryByCustomString(context, custom);
}
void Application_Start(object sender, EventArgs e)
{
// Enable Push SQL cache dependencies
//string conString = WebConfigurationManager.ConnectionStrings["MyMovies"].ConnectionString;
//SqlDependency.Start(conString);
HttpContext context = HttpContext.Current;
context.Cache.Insert(
"MovieKey",
DateTime.Now,
null,
DateTime.MaxValue,
Cache.NoSlidingExpiration,
CacheItemPriority.NotRemovable,
null);
}
</script>
下面代码中,当插入一条新记录时,Moviekey项目会重新传入缓存中,此时,每一个依赖于这个键值的DataSource会自动载入更改后的数据。
Code
<%@ 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 dtlMovie_ItemInserted(object sender, DetailsViewInsertedEventArgs e)
{
Cache.Insert("MovieKey", DateTime.Now);
Response.Redirect("~/DataSourceKeyDependency.aspx");
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Add Movie Key Dependency</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>Add Movie</h1>
<asp:DetailsView
id="dtlMovie"
DefaultMode="Insert"
DataSourceID="srcMovies"
AutoGenerateRows="false"
AutoGenerateInsertButton="true"
OnItemInserted="dtlMovie_ItemInserted"
Runat="server">
<Fields>
<asp:BoundField
DataField="Title"
HeaderText="Title:" />
<asp:BoundField
DataField="Director"
HeaderText="Director:" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource
id="srcMovies"
ConnectionString="<%$ ConnectionStrings:Movies %>"
InsertCommand="INSERT Movies (Title, Director)
VALUES (@Title, @Director)"
Runat="server" />
</div>
</form>
</body>
</html>