C# 中的 SQL 依赖关系
我试图弄清楚如何使用 SQL 依赖项(C# 4.0)来“侦听”数据库的更改。我在网上看到了很多东西,但它们似乎是(自然地)定制的,用于使用依赖项来提取 SQL 依赖项所依赖的相同数据。例如,本文。
我想做的是创建一个依赖项,当触发时,会产生许多不同的 SQL“选择”查询(我可以将其存储在其他方法等中)。例如:我正在尝试设置一个依赖项来监视表中的行数。当行数增加时,然后执行 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();
}
I'm trying to figure out how to use SQL Dependency (C# 4.0) to 'listen' for changes to a database. I've seen quite a few things on the web, but they seem to be tailored (naturally) for using the dependency to pull the same data that the SQL Dependency is dependent on. For example, this article.
What I'm trying to do is create a dependency that, when triggered, results in a number of different SQL 'Select' queries (which I can store in other methods etc). For example: I'm trying to set a dependency that watches the number of rows in table. When the number of rows increases, then do x, y, z (ie my program doesn't care what the number of rows is, just that it's increased, and when it does do a bunch of things).
Any thoughts on what would the best way to do this?
EDIT: I've attached my code as I have it currently. I'm trying to figure out how to separate setting up the SqlDependency from the GetData() process. Currently though, I think I go into a bit of an endless loop as after I remove the event handler and rerun "SetupSqlDependency()", it goes right back into the event handler
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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以连接 SqlDependency.Change 事件并在此事件处理程序中执行您喜欢的任何操作。事实上,这是做你想做的事的唯一方法,并且没有什么错。
在伪代码中,它看起来像这样:
非常简单。只需使用两个不同的查询即可。
编辑:在您的示例代码中,有一条注释说您正在 UI 线程上运行。为什么会这样呢?我对此表示怀疑。无论如何,您应该在重置依赖项之前运行查询,否则您将有可能发生并发失效。
我建议您从数据库获取新数据,然后向 ui 发送消息以更新它(调用)。
You can hook up the SqlDependency.Change event and do whatever you like in this event handler. This is, in fact, the only way to do what you want, and there is nothing wrong with it.
In pseudo-code it looks like this:
Very simple. Just use two different queries.
Edit: In your sample code there is a comment saying you are running on the UI thread. Why should that be the case? I doubt it. Anyway, you should run your query before you resetup the dependency because otherwise you will have the potential for concurrent invalidations happening.
I suggest you get your fresh data from the database and then send a message to the ui to update it (Invoke).