SqlDependency类的使用
简介:
SqlDependency提供了这样一种能力:当被监测的数据库中的数据发生变化时,SqlDependency会自动触发OnChange事件来通知应用程序,从而达到让系统自动更新数据(或缓存)的目的。
应用场景:
当数据库中的数据发生变化时,需要更新缓存,或者需要更新与之相关的业务数据,又或者是发送邮件或者短信什么的等等情况时,如果数据库是SQL Server,可以考虑使用SqlDependency监控数据库中的某个表的数据变化,并出发相应的事件。
应用程序前提条件:
在应用程序启动时,启动SqlDependency针对SQLServer连接的监控。
在应用程序结束时,停止SqlDependency针对SQLServer连接的监控。
Web应用程序:
protectedvoid Application_Start()
{
System.Data.SqlClient.SqlDependency.Start(ConfigurationManager.ConnectionStrings["Framework_SqlServer"].ConnectionString);
}
protectedvoid Application_End(object sender, EventArgs e)
{
System.Data.SqlClient.SqlDependency.Stop(ConfigurationManager.ConnectionStrings["Framework_SqlServer"].ConnectionString);
}
WINDOWS应用程序:
staticvoid Main(string[] args)
{
_connStr = ConfigurationManager.ConnectionStrings["Framework_SqlServer"].ToString();
SqlDependency.Start(_connStr);//传入连接字符串,启动基于数据库的监听
…
SqlDependency.Stop(_connStr);//传入连接字符串,启动基于数据库的监听
}
具体应用:
//当表中的数据发生变化时,出发OnChangeEventHandler事件
privatestaticvoid UpdateGrid()
{
using (SqlConnection connection = newSqlConnection(_connStr))
{
//依赖是基于某一张表的,而且查询语句只能是简单查询语句,不能带top或*,同时必须指定所有者,即类似[dbo].[]
using (SqlCommand command = newSqlCommand(" SELECT ID,TaskName,CompletionNumber,UploadFilePath,QueryCount,StartTime,EndTime,TaskStatus,DownLoadFilePath,Creater,CreateDate FROM [dbo].[Res_BatchQuery] WHERE ID = 70 ", connection))
{
command.CommandType = CommandType.Text;
connection.Open();
SqlDependency dependency = newSqlDependency(command);
dependency.OnChange += newOnChangeEventHandler(dependency_OnChange);
SqlDataReader sdr = command.ExecuteReader();
Console.WriteLine();
while (sdr.Read())
{
Console.WriteLine("Id:{0}\\TaskName:{1}\\CompletionNumber:{2}", sdr["ID"].ToString(), sdr["TaskName"].ToString(), sdr["CompletionNumber"].ToString());
}
sdr.Close();
}
}
}
//具体事件
privatestaticvoid dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change) //只有数据发生变化时,才重新获取并数据
{
UpdateGrid();
}
}
需要注意的事项:
1、应用程序开始或者结束时,必须相应的开始或者停止对SQL Server的监控。
2、只有SQL语句中需要查询的字段才会被监控,没有查询的数据发生变化时,并不会触发dependency_OnChange事件。
3、查询语句只能是简单查询语句,不能带top或*,同时必须指定所有者,即类似[dbo].[]。
4、WHERE条件中的数据不能太复杂,不然可能不会被监控到。
5、待查询的字段的数据也不能太复杂。测试时,有个字段保存Json格式的数据。如果将这个字段也写入到SQL语句中,则不会被监控到。
SQLServer需要的相关配置:
//设置某个数据库代理的回滚
ALTER DATABASE [DBName] SET NEW_BROKER WITH ROLLBACK IMMEDIATE;
//设置某个数据库的代理
ALTER DATABASE [DBName] SET ENABLE_BROKER;
//查询某个数据库是否已经启动了代理
SELECT is_broker_enabled FROM sys.databases WHERE name = '[DBName]'
is_broker_enabled 为0表示未启动代理
is_broker_enabled 为1表示已启动代理