观察sql数据库中的表新记录
本文关键字:新记录 sql 数据库 观察 | 更新日期: 2023-09-27 18:02:35
我在windows应用程序中使用EF,我希望我的应用程序在某个表中插入新记录时执行一些任务"这些新记录将由使用相同数据库的网站插入"
我的问题是如何观察这个表的变化,并在出现新记录时得到通知,EF在这种情况下可以帮助我吗?
更新:我使用了SqlDependency类并在db
中使用了它。 ALTER DATABASE UrDb SET ENABLE_BROKER
并且还在数据库中创建了一个服务和一个队列http://screencast.com/t/vrOjJbA1y,但我从未从我的windows应用程序得到通知。
此外,当我打开队列在sql server它总是空http://screencast.com/t/05UPDIwC8ck接缝,有什么问题,但我不知道。
我的建议如下:
-
如果您能够添加重复表到数据库,那么这里是一个解决方案。您有table1和table2 (table1的副本)。当您向table1插入新记录时,您可以将它们与table2中的现有记录进行比较,从而找到新记录。比较之后,应该将所有新记录添加到table2中。这是某种同步。
-
你不需要其他桌子了。你可以将所有数据存储在应用程序缓存中,并检查一段时间(例如5秒)是否有任何新的事件,这些事件不存在于你的缓存中。如果它们不存在-在日志或其他地方通知它们,并将它们添加到缓存中。但是如果记录太多,处理时间会大大增加+内存消耗。
-
如果你能够改变db,那么你可以添加一些像'isNew'列到你的表。当一个新的数据来自网站时,该列将为"真",您的程序可以跟踪这一点,并在处理后为每个记录设置此标志为假。(如果网站不能设置此标志,可以使用SQL TRIGGER AFTER INSERT将标志值设置为true。如果它是第三方网站,或者你不想在那里改变任何东西,网站甚至无法知道这个功能)
-
这是关于EF变化跟踪的文章:http://blogs.msdn.com/b/adonet/archive/2009/06/10/poco-in-the-entity-framework-part-3-change-tracking-with-poco.aspx
但问题是,你应该通过EF检查整个表的变化,这会影响你的应用程序的性能。
以下是关于SQL Server端更改跟踪和实现概念的有用信息:http://www.mssqltips.com/sqlservertip/1819/using-change-tracking-in-sql-server-2008/http://msdn.microsoft.com/en-us/library/bb933994.aspx或者使用SqlTableDependency: https://tabledependency.codeplex.com/。这个开源组件向您发送一个事件,其中包含关于表
中的新行的记录详细信息,请参见Change Data Capture,特别是sys.fn_cdc_get_max_lsn
。这将创造一个寻找变化的地方。
然后,编写一个存储过程来轮询该视图。让它捕获之前的值,并循环查找与您的数据到达率适当的WAITFOR
延迟的变化。
当过程注意到最高的LSN发生了变化时,让它做一些事情。它可以选择行。它也可以只打印一条消息。然后它回到了它的投票站(事实上)。
打印消息可能听起来很奇怪,不知道EF的第一件事(并且对这类事情严重过敏),我不知道它是否会在这里帮助你。但原则上是应该的,因为底层通信是存在的。
从您的应用程序调用该过程。当过程执行T-SQL PRINT
(或RAISERROR
)语句时,将向客户端发送一条消息。它在EF中的位置或者你如何处理它,我不能说,但它应该在有用的地方,因为在一般情况下它会显示给用户。在您的示例中,应用程序将查找特定的消息号或文本,并做出相应的反应。(当然,您希望正常处理其他消息。)
这种方法既便宜又简单。它几乎不使用服务器资源,仅在发生更改时才向客户端发送消息,不使用额外的表,几乎不依赖于用户编写的代码,并且可以通过查看sysprocesses
来验证是否正在运行。
可以创建一个SQLCLR触发器FOR INSERT到表。这个触发器可以调用一个简单的WCF服务,您可以在应用程序中托管该服务。具有触发器的程序集需要在SQL Server中注册。请看这里怎么做。
另一种方法(最简单的一种):使用普通的SQL触发器监视对表的insert,并使用类似"copy nul/Y some_file_with_path.txt"这样的命令执行xp_cmdshell。您的应用程序可以使用FileSystemWatcher类来监视对同一文件的修改。将过滤器配置为仅监视对该特定文件的最后访问。看看这里怎么做。xp_cmdshell的代理帐户需要在SQL Server上定义。
我之前也遇到过同样的问题。我也无法使SQl通知工作。
另一个建议是使用钩子你可以重写SaveChanges并执行你的自定义逻辑。
https://stackoverflow.com/a/7654423/989679, https://github.com/kmckelvin/EFHooks/blob/master/EFHooks/HookedDbContext.cshttp://thedatafarm.com/blog/data-access/objectcontext-savechanges-is-now-virtual-overridable-in-ef4/(archive)
创建一个事务表,用于存储网站插入的事务信息。
在插入表上创建一个插入触发器,在事务表中添加一条新记录。
那么你只需要你的windows应用程序定期检查事务表,当它发现什么做任何你想要的,然后清除事务表上的记录。
它不是很优雅,但它可能有效。我不熟悉EF,我不知道它是否有更好的解决方案。