2012-01-24 70 views
4

我想弄清楚如何使用SQL依赖关系(C#4.0)来侦听对数据库的更改。我在网上看到了很多东西,但是他们似乎是自然而然地使用依赖关系来提取SQL依赖关系所依赖的相同数据。例如,this article在C#中的SQL依赖关系

我想要做的是创建一个依赖关系,当触发时,会导致大量不同的SQL Select(查询可以存储在其他方法等)查询。例如:我试图设置一个依赖项来监视表中的行数。当行数增加时,则执行x,y,z(即我的程序不关心行数是多少,只是它增加了,什么时候它做了很多事情)。

有什么想法是最好的方法来做到这一点?

编辑:我已经附上我的代码,因为我有它目前。我想弄清楚如何从GetData()过程中分离设置SqlDependency。目前,虽然,我觉得我走进了一下一个无限循环的作为后,我删除了事件处理程序,然后重新运行“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(); 

    } 

回答

5

你可以连接起来的SqlDependency 。改变事件并在这个事件处理器中做任何你喜欢的事情。事实上,这是做你想做的事情的唯一方法,它没有任何问题。

在伪代码看起来是这样的:

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

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

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

我建议你从数据库中获取新鲜的数据,然后发送消息给UI来更新它(调用)。

+0

我想我很困惑的是,他们将设置依赖关系的过程与“GetData”材质结合在一起。我试图找出如何分开它,如果它需要 – keynesiancross

+0

编辑阐述你的观点。 – usr

+1

谢谢 - 尽管您在哪里获得.Change事件?我只获得OnChange事件? (或者我设法跨越语言...)。我已经更新了我的问题以包含我的当前代码 – keynesiancross