直接上代码 :
声明部分 :
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.sqlClient;
using System.Data;
using System.Configuration;
using System.Windows.Forms;
namespace FrontAlarm
{
public class sqlServicebroker
{
private string connectionStr = "Data Source=.;Initial Catalog=Test;User ID=cc;Password=cc;";
private string sqlStr = "";
private sqlConnection connection = null;
public delegate void UIDelegate();
private UIDelegate uidel = null;
public Form form = null;
/// <summary>
///
/// </summary>
/// <param name="TableName"></param>
/// <param name="ColumnNames"></param>
public sqlServicebroker(string TableName,List<string> ColumnNames)
{
string columns = "";
foreach (string str in ColumnNames)
{
if (columns != "")
columns = columns + ",";
columns = columns + "[" + str + "]";
}
this.sqlStr = string.Format("select {0} From [dbo].[{1}]",columns,TableName);
}
/// <summary>
/// </summary>
/// <param name="constr"></param>
/// <param name="TableName"></param>
/// <param name="ColumnNames"></param>
public sqlServicebroker(string constr,string TableName,List<string> ColumnNames)
: this(TableName,ColumnNames)
{
this.connectionStr = "Data Source=.;Initial Catalog=Test;User ID=cc;Password=cc;";ConfigurationManager.ConnectionStrings[constr].ToString();
}
/// <summary>
///
/// </summary>
~sqlServicebroker()
{
StopDependency();
connection.dispose();
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool EnoughPermission()
{
sqlClientPermission perm = new sqlClientPermission(System.Security.Permissions.PermissionState.Unrestricted);
try
{
perm.Demand();
return true;
}
catch (System.Exception)
{
return false;
}
}
/// <summary>
///
/// </summary>
/// <param name="uidelegate"></param>
public void InitDependency(UIDelegate uidelegate)
{
sqlDependency.Stop(connectionStr);
sqlDependency.Start(connectionStr);
if (connection == null)
connection = new sqlConnection(connectionStr);
if (!EnoughPermission())
throw new Exception("没有权限(sqlClientPermission)!");
if (uidelegate == null)
throw new Exception("回调方法未指定(UIDelegate)!");
if (connection == null)
throw new Exception("未初始化(InitDependency)!");
this.uidel = uidelegate;
}
/// <summary>
/// 传入窗体对象,以防止委托有需要访问UI层控件是引发的“从不是创建控件的线程访问它”
/// </summary>
/// <param name="form1"></param>
/// <param name="uidelegate"></param>
public void InitDependency(Form form1,UIDelegate uidelegate)
{
InitDependency(uidelegate);
this.form = form1;
}
/// <summary>
///
/// </summary>
public void StartDependency()
{
//这里很奇怪,每次都需要新的command对象
using (sqlCommand command = new sqlCommand(sqlStr,connection))
{
command.Notification = null;
sqlDependency dependency = new sqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
if (connection.State != ConnectionState.Open)
connection.open();
command.ExecuteNonQuery();
command.dispose();
}
}
/// <summary>
///
/// </summary>
public void StopDependency()
{
sqlDependency.Stop(connectionStr);
if (connection != null)
connection.Close();
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dependency_OnChange(object sender,sqlNotificationEventArgs e)
{
//注销监测事件
sqlDependency dependency = (sqlDependency)sender;
dependency.OnChange -= dependency_OnChange;
//放在移除事件之后又很大必要,防止ui层调用更新相同表时,进入循环出发调用
//uidel.Invoke();
//uidel();
//使用from.Invoke调用防止访问界面控件引发“从不是创建控件的线程访问它”
if (form != null)
form.Invoke(uidel);
else
uidel();
//再次启动监听
StartDependency();
}
}
}
调用:
sqlServicebroker broker;
private void Dependbrok()
{
//需要监测的列
List<string> columns = new List<string>();
columns.Add("test1");
columns.Add("test2");
string table = "Test";
broker = new sqlServicebroker(table,columns);
//实例化毁掉函数
sqlServicebroker.UIDelegate uidel = new sqlServicebroker.UIDelegate(writeCon);
//初始化,及传入回调函数
broker.InitDependency(uidel);
//初始化,传入窗体对象对于需要委托中访问ui控件的情况
//broker.InitDependency(this,uidel);
//启动监听
broker.StartDependency();
//MessageBox.Show("启动");
}
//监听的数据有变化时触发
private void writeCon()
{
MessageBox.Show("数据有变化o(∩_∩)o 哈哈");
}
关于sqlDependency类,很多人无法测试成功,因为它的限制很多,功能可能有待加强,稍微不注意就会让上面的代码陷入死循环。特别要注意的就是command的sql语句问题:
select id,name from dbo.test where id <>4 order by id desc
很遗憾,他只能支持上面这样的简单语句
列明必须写,不能用*,不能用top,不能用函数,包括聚合函数,不能用子查询,包括where后的子查询,不能用外连接,自连接,不能用临时表,不能用变量,不能用视图,不能垮库,而且表名之前必须加类似dbo这样的前缀....具体有多少限制,基本上除了上述的格式或者比上述更简单的格式,其他的都不可以。
注意
如果在数据库中执行 ‘ALTER DATABASE dbTest SET ENABLE_broKER ’ 出现死循环 执行下列语句就可以了
ALTER DATABASE dbTest SET NEW_broKER WITH ROLLBACK IMMEDIATE
ALTER DATABASE dbTest SET ENABLE_broKER
如果有没成功的 可以给我留言 我解决了这个 希望可以帮到需要的同胞
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。