mj2*_*2k2 22 c# wpf sqldependency
我正在使用SQLDependency来通知我数据库是否有变化.程序启动后,它工作得很好.当我进行第一次更改时,事件会触发.Wohoo ......太好了.但如果我做了第二次更改,事件就不再发生了.我搜索了所有网络,但我没有发现任何有关此问题的信息.仅发现OnChange-Event在循环中触发的问题.谁能帮我?
这里有一小段代码:
private void GetStates()
{
if (!DoesUserHavePermission())
return;
SqlDependency.Stop(con);
SqlDependency.Start(con);
using (SqlConnection cn = new SqlConnection(con))
{
using (SqlCommand cmd = cn.CreateCommand())
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT Bla, Bla2, ..FROM dbo.[BLA3]"
cmd.Notification = null;
cmd.Dispose();
SqlDependency dep = new SqlDependency(cmd);
dep.OnChange += new OnChangeEventHandler(dep_OnChange);
cn.Open();
using (SqlDataReader dr = cmd.ExecuteReader())
{
state.Clear(); //In this Case "state" is a List<string>
while (dr.Read())
{
state.Add(dr.GetString(0) + "|" + dr.GetInt32(3));
}
dr.Dispose();
dr.Close();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的OnChange-Event看起来像这样:
private void dep_OnChange(object sender, SqlNotificationEventArgs e)
{
SqlDependency dep = sender as SqlDependency;
dep.OnChange -= this.dep_OnChange;
using (SqlConnection cn = new SqlConnection(con))
{
using (SqlCommand cmd = cn.CreateCommand())
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT Bla, Bla2, ..FROM dbo.[BLA3]";
cmd.Notification = null;
if (e.Type == SqlNotificationType.Change)
{
if (cn.State != ConnectionState.Open)
{
cn.Open();
}
using (SqlDataReader dr = cmd.ExecuteReader())
{
state.Clear(); // Clear and Refill the stringlist "state"
while (dr.Read())
{
state.Add(dr.GetString(0) + "|" + dr.GetInt32(3));
}
}
}
cn.Close();
}
}
this.GetStates(); //to go ahead and wait for a new change
}
Run Code Online (Sandbox Code Playgroud)
问题出在哪儿?
leh*_*058 11
我也遇到了这个问题.您需要创建一个新的SqlDependency实体(在取消订阅OnChange事件中的现有实体之后),然后运行新的ExecuteReader命令.我从这篇文章中得到了这个想法:
http://www.codeproject.com/Articles/12335/Using-SqlDependency-for-data-change-events
这通常是有道理的,因为一旦您收到更改通知,您通常会想要重新查询数据.
数据库第一次发生变化后,需要再次执行命令并重新订阅事件。
以下代码对我有用。
class Program
{
static string connectionString = "Server=.;Database=test_sql_dependency;Integrated Security=True;";
static void Main(string[] args)
{
// 1. create database
// 2. enable service broker by executing this sql command on the database.
// alter database test_sql_dependency set enable_broker
// 3. start sql dependency, for some sql server connection string or with queue if you want.
//var queueName = "myFirstQueue";
//SqlDependency.Start(connectionString, queueName);
SqlDependency.Start(connectionString);
// complete the rest of the steps in seperate method to be able to call it again when you need to
// re-subscribe to the event again, becuase by default it will be executed only one time
RegisterSqlDependency();
Console.WriteLine("Listening to database changes...");
Console.ReadLine();
}
static void RegisterSqlDependency()
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
if (connection.State != System.Data.ConnectionState.Open)
{
connection.Open();
}
// 4. create a sql command
// you can't say select *, and also you have to specefy the db owner (dbo.)
SqlCommand command = new SqlCommand("select Id, Name from dbo.Employee", connection);
// 5. create dependency and associtate it to the sql command
SqlDependency dependency = new SqlDependency(command);
// 6. subscribe to sql dependency event
dependency.OnChange += new OnChangeEventHandler(OnDependencyChange);
// 7. execute the command
using (SqlDataReader reader = command.ExecuteReader())
{
}
}
}
static void OnDependencyChange(object sender, SqlNotificationEventArgs e)
{
var InsertOrUpdateOrDelte = e.Info;
//-----------------------------Finally-------------------------
// after you knew that there is a change happened
// you have to unsubscribe the event and execute the command again and then re-subscribe to the event
// 1. unsubscribe the event
SqlDependency dependency = sender as SqlDependency;
dependency.OnChange -= OnDependencyChange;
// 2. re-subscribe to the event and execute the command again
RegisterSqlDependency();
}
}
Run Code Online (Sandbox Code Playgroud)
不确定这是否是您的问题,但您在创建命令后立即处理该命令:
using (SqlCommand cmd = cn.CreateCommand())
{
...
cmd.Dispose();
Run Code Online (Sandbox Code Playgroud)
它看起来像一个错误。
| 归档时间: |
|
| 查看次数: |
7480 次 |
| 最近记录: |