sqldependency 的替代方案

Alternative for sqldependency

我有一个保存聊天信息的 mssql table。它有计算列,有数百万行,并且正在被第三方应用程序used/populated。现在我想使用这个 table 在我的网站上显示聊天记录,并且将来可能能够使用 signalr 发送消息。 我使用 sqldependency 做了几个测试,它有效,但仅适用于对我的情况没有帮助的特定查询(我必须排除计算列,无法按最后一条消息排序,无法设置前 100 条消息等)

所以我的问题是什么是替代方案?使用每 x 秒轮询一次数据库的网络服务?

旁注,我对 table 完全没有影响。

我觉得你还是可以用SqlDependency,如果你再考虑一下你的实际需求。

您用于检测更改的查询不必与用于获取 更改的查询相同。所以你可以

select id from chat where chatRoomId = 123

作为 "detect changes query"。这只会告诉你 "There's a new message. Or more.",没有别的。然后,要获取实际的新行,您可以使用复杂的查询:

select 
 top 100 someComplexColumn, everythingElse 
from chat 
where chatRoomId = 123 
order by messageTime desc

只要 "detect changes query" 能够很好地将您不关心的大部分更改与您 关心的更改区分开来,您就美好的。请记住,SqlDependency 实际上并没有告诉您 更改了什么 或有关数据的任何其他信息。它不关心有多少数据适合查询 now - 它只跟踪适合您指定的过滤器的更改。由于聊天消息通常是不可变的,因此您可以只检查 id 列(例如 "new item")。如果您的聊天消息是可编辑的,您还必须在 "detect changes query".

中添加一些 changedOn

SqlDependency 的一个很好的替代方法是 SqlDependencyEx. It doesn't have its memory leak problems,它使用数据库触发器和本机 Service Broker 通知来接收有关 table 更改的事件。这是一个用法示例:

int changesReceived = 0;
using (SqlDependencyEx sqlDependency = new SqlDependencyEx(
          TEST_CONNECTION_STRING, TEST_DATABASE_NAME, TEST_TABLE_NAME)) 
{
    sqlDependency.TableChanged += (o, e) => changesReceived++;
    sqlDependency.Start();

    // Make table changes.
    MakeTableInsertDeleteChanges(changesCount);

    // Wait a little bit to receive all changes.
    Thread.Sleep(1000);
}

Assert.AreEqual(changesCount, changesReceived);

使用 SqlDependecyEx 您可以分别监视 INSERTDELETEUPDATE 并在事件参数中接收实际更改的数据 (xml)目的。过滤传入消息可帮助您实现理想的行为。希望对您有所帮助。