图:在SQL Server 2005与SQL Server 2008中监视数据的变化
SQL Server 2005与SQL Server 2008监控对特定 SQL 命令的结果集的更改。如果数据库中发生了将修改该命令的结果集的更改,依赖项便会使缓存的项失效。此功能使得SQL Server 2005与SQL Server 2008可以提供行级别的通知。
要使用SQL Server 2005与SQL Server 2008缓存依赖,你首先要做的就是启用通知,即确保数据库具有enable_broker标记设置。你可以用下面的SQL语句来执行这个动作:
use ASPNET4
alter database ASPNET4 set enable_broker
通知支持 Select 查询和存储过程,支持多个查询和嵌套查询,但必须遵循如下规则:
1)必须提供完全限定的表名,其中包括所有者名称,例如dbo.employee,如果你只写成employee就是不正确的。
2)查询不支持聚合操作,例如count()、max()、min()或者average()。
3)查询不能够使用通配符号(*)选择所有列。
如下面就是一个可接受的命令:
select employeename from dbo.employee
下面将通过一个详细的示例来阐述如何使用SQL Server 2005与SQL Server 2008缓存依赖。首先,我们需要在SqlServerDependency.aspx页面里定义了三个控件。其中,bt_Update控件用于修改数据库数据,bt_GetData控件用于获取缓存数据情况,lblInfo控件用于显示相关的操作信息。页面代码如代码清单19-1所示:
代码清单19-1:SqlServerDependency.aspx
< %@ Page Language="C#" AutoEventWireup="true"
CodeBehind="SqlServerDependency.aspx.cs"
Inherits="_19_1.SqlServerDependency" %>
<!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></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="bt_Update" runat="server"
Height="24px" Text="修改表" Width="100px"
OnClick="bt_Update_Click" />
<asp:Button ID="bt_GetData" runat="server"
Height="24px" Text="获取数据" Width="100px"
OnClick="bt_GetData_Click" />
<br />
<br />
<asp:Label ID="lblInfo" runat="server"
BorderStyle="Dotted" BorderWidth="1px"
Font-Size="12px" Width="500px">
</asp:Label>
</div>
</form>
</body>
</html>
下面,我们需要在代码里完成这样几个功能:
首先,在页面的Page_Load事件了创建一个SqlCacheDependency缓存依赖项;然后,在bt_GetData_Click事件里获取缓存数据的存在与否;最后,在bt_Update_Click事件里修改dbo.employee 表的employeename字段的值,从而使缓存项自动移除。如代码清单19-2所示:
代码清单19-2:SqlServerDependency.aspx.cs
using System;
using System.Data;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Web.Caching;
using System.Web.Configuration;
namespace _19_1
{
public partial class SqlServerDependency : System.Web.UI.Page
{
private SqlCacheDependency dependency;
private string connectionString =
WebConfigurationManager.ConnectionStrings
["ConnectionString"].ConnectionString;
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
SqlDependency.Stop(connectionString);
SqlDependency.Start(connectionString);
lblInfo.Text += "开始创建依赖项...<br />";
Cache.Remove("employee");
DataTable dt = GetTable();
Cache.Insert("employee", dt, dependency);
lblInfo.Text += "添加依赖项:
Cache.Insert(\"employee\", dt, dependency)<br />";
}
}
private DataTable GetTable()
{
SqlConnection con =
new SqlConnection(connectionString);
using (con)
{
string sql = "select employeename from dbo.employee";
SqlDataAdapter da = new SqlDataAdapter(sql, con);
dependency =
new SqlCacheDependency(da.SelectCommand);
DataSet ds = new DataSet();
da.Fill(ds, "employee");
return ds.Tables[0];
}
}
protected void bt_Update_Click(object sender, EventArgs e)
{
SqlConnection con =
new SqlConnection(connectionString);
using (con)
{
string sql = "update dbo.employee set
employeename='mawei10' where employeeid=10";
SqlCommand cmd = new SqlCommand(sql, con);
con.Open();
cmd.ExecuteNonQuery();
}
lblInfo.Text +=
"执行bt_Update_Click事件,修改完成.<br />";
}
protected void bt_GetData_Click(object sender, EventArgs e)
{
if (Cache["employee"] == null)
{
lblInfo.Text += "执行bt_GetData_Click事件,
Cache[\"employee\"]数据不存在.<br />";
}
else
{
lblInfo.Text += "执行bt_GetData_Click事件,
Cache[\"employee\"]数据还存在.<br />";
}
}
}
}
在上面的代码中,SqlDependency 对象表示应用程序和 SQL Server 2005 实例间的查询通知依赖关系。其中:
SqlDependency.Start 方法启动用于接收依赖项更改通知的侦听器,该通知来自由连接字符串指定的 SQL Server 实例。如果侦听器初始化成功,则为 true;如果已存在兼容的侦听器,则为 false。
SqlDependency.Stop 方法用于停止在上一次 Start 调用中指定的连接的侦听器。如果侦听器完全停止,则为 true;如果 AppDomain 从侦听器解除绑定,但至少还有一个其他 AppDomain 使用同一侦听器,则为 false。
示例运行结果如图所示: