SqlDependency类的使用

Posted Bright Liu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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].[]

4WHERE条件中的数据不能太复杂,不然可能不会被监控到。

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表示已启动代理

以上是关于SqlDependency类的使用的主要内容,如果未能解决你的问题,请参考以下文章

使用SqlDependency与表的定期轮询(对性能的影响)

在作为 Windows 服务托管的 WCF 类库项目中使用 SqlDependency

SqlDependency通知sql server 2005不会在多个插入上触发

如何从 SQL Server 内存中清除 SqlDependency?

核心 2.1 SignalR 和 SQLDependency

使用SqlDependency实时监听SQL server数据库变化并执行事件