一个SqlDependency对象可以和一个SqlCommand绑定,用于去监测查询结果与最初的查询相比何时发生变化。
你可以赋值一个委托给SqlDependency的OnChange事件,当监测的数据库表查询发生改变时会触发该委托。当然在你执行该SqlCommand之前,你必须将SqlDependency与该SqlCommand关联。
SqlDependency的HasChanges属性也可以用于判断表的查询结果是否发生改变。
安全性考虑
Sqldependency机制依赖于SqlConnection,所以调用Start方法时,SqlConnection必须是打开的,以便于接受我们监测的表发生改变的通知。通过SqlClientPermission的使用来控制SqlDependency.Start的初始化,更多信息请看https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/enabling-query-notifications
实例
The following steps illustrate how to declare a dependency, execute a command, and receive a notification when the result set changes:
以下步骤说明了如何定义一个dependency、执行一个Command以及当监测结果改变时接受通知。
-
向Server初始化一个SqlDependency 连接。
-
创建SqlConnection和SqlCommand对象去连接服务器,并定义好Transact-SQL 语句
-
创建一个新的
SqlDependency
对象或者使用一个已经定义好的,并将它与SqlCommand对象绑定。本质上,这是创建了一个SqlNotificationRequest对象,并且将它与我们的SqlCommand对象绑定。这个notification request对象包含了一个标识,它唯一的标识了该SqlDependency
对象。同时它也启动了一个客户端监听器。 -
向
SqlDependency
的OnChange事件订阅了一个事件句柄 -
使用SqlCommand对象任意Execute方法去执行该Command。因为该Command与notification对象绑定在一起,服务器认为它必须生成一个notification并且队列消息会指向dependencies队列。
-
关闭
SqlDependency
到服务器的连接。
之后如果任何用户修改了我们监测的数据, Microsoft SQL Server会监测到此修改,抛出一个通知并通过指定的SqlConnection给到我们通过SqlDependency.Start创建的客户端。客户端监听器收到这条通知后,会定位到所关联的SqlDependency对象并触发OnChange事件。
下面这段代码片段展示了一段你可以用到的设计模式去创建一个样板程序。
void Initialization()
{
// Create a dependency connection.
SqlDependency.Start(connectionString, queueName);
}
void SomeMethod()
{
// Assume connection is an open SqlConnection.
// Create a new SqlCommand object.
using (SqlCommand command=new SqlCommand(
"SELECT ShipperID, CompanyName, Phone FROM dbo.Shippers",
connection))
{
// Create a dependency and associate it with the SqlCommand.
SqlDependency dependency=new SqlDependency(command);
// Maintain the reference in a class member.
// Subscribe to the SqlDependency event.
dependency.OnChange+=new
OnChangeEventHandler(OnDependencyChange);
// Execute the command.
using (SqlDataReader reader = command.ExecuteReader())
{
// Process the DataReader.
}
}
}
// Handler method
void OnDependencyChange(object sender,
SqlNotificationEventArgs e )
{
// Handle the event (for example, invalidate this cache entry).
}
void Termination()
{
// Release the dependency.
SqlDependency.Stop(connectionString, queueName);
}
另外,数据库要首先做以下设置:
USE [数据库名称]
ALTER DATABASE 数据库名称 SET NEW_BROKER WITH ROLLBACK IMMEDIATE;
GO
ALTER DATABASE 数据库名称 SET ENABLE_BROKER;
GO