C#中的SQL依赖关系

我正在试图弄清楚如何使用SQL依赖(C#4.0)来“监听”数据库的更改。 我在Web上看到了很多东西,但它们似乎(自然地)用于使用依赖项来提取SQL依赖关系所依赖的相同数据。 例如, 这篇文章 。

我要做的是创建一个依赖项,当被触发时,会产生许多不同的SQL“Select”查询(我可以将其存储在其他方法中等)。 例如:我正在尝试设置一个监视表中行数的依赖项。 当行数增加时,则执行x,y,z(即我的程序不关心行数是多少,只是它增加了,当它确实做了很多事情时)。

关于最好的方法是什么的任何想法?

编辑:我已经附上了我目前的代码。 我试图找出如何分离设置SqlDependency和GetData()过程。 目前,我认为我进入一个无限循环,因为我删除事件处理程序并重新运行“SetupSqlDependency()”后,它会回到事件处理程序

private void SetupSQLDependency() { // Tutorial for this found at: // http://www.dreamincode.net/forums/topic/156991-using-sqldependency-to-monitor-sql-database-changes/ SqlDependency.Stop(connectionString); SqlDependency.Start(connectionString); sqlCmd.Notification = null; // create new dependency for SqlCommand SqlDependency sqlDep = new SqlDependency(sqlCmd); sqlDep.OnChange += new OnChangeEventHandler(sqlDep_OnChange); SqlDataReader reader = sqlCmd.ExecuteReader(); } private void sqlDep_OnChange(object sender, SqlNotificationEventArgs e) { // FROM: http://msdn.microsoft.com/en-us/a52dhwx7.aspx #region // This event will occur on a thread pool thread. // Updating the UI from a worker thread is not permitted. // The following code checks to see if it is safe to // update the UI. /* ISynchronizeInvoke i = (ISynchronizeInvoke)this; // If InvokeRequired returns True, the code // is executing on a worker thread. if (i.InvokeRequired) { // Create a delegate to perform the thread switch. OnChangeEventHandler tempDelegate = new OnChangeEventHandler(sqlDep_OnChange); object[] args = { sender, e }; // Marshal the data from the worker thread // to the UI thread. i.BeginInvoke(tempDelegate, args); return; }*/ #endregion // Have to remove this as it only work's once SqlDependency sqlDep = sender as SqlDependency; sqlDep.OnChange -= sqlDep_OnChange; // At this point, the code is executing on the // UI thread, so it is safe to update the UI.. // 1) Resetup Dependecy SetupSQLDependency(); } 

您可以连接SqlDependency.Change事件并在此事件处理程序中执行您喜欢的任何操作。 事实上,这是做你想做的事的唯一方法,而且没有任何问题。

在伪代码中,它看起来像这样:

 var dep = new SqlDependency(GetSqlQueryForMonitoring()); dep.Change += () => { var data = ExecSql(GetDataQuerySql()); UpdateCache(data); }; 

非常简单。 只需使用两个不同的查询。

编辑:在您的示例代码中有一条评论说您正在UI线程上运行。 为什么会这样呢? 我对此表示怀疑。 无论如何,您应该在重置依赖项之前运行查询,否则您将有可能发生并发失效。

我建议你从数据库中获取新数据,然后向ui发送一条消息来更新它(Invoke)。