我有多个应用程序访问同一个数据库,我需要在其中一个应用程序更改某个表格(更新、插入)时得到通知。
数据库和应用程序不在同一台服务器上。
我有多个应用程序访问同一个数据库,我需要在其中一个应用程序更改某个表格(更新、插入)时得到通知。
数据库和应用程序不在同一台服务器上。
您可以使用SqlDependency Class
。它的主要用途是为ASP.NET页面提供服务(客户端通知数量较少)。
ALTER DATABASE UrDb SET ENABLE_BROKER
实现OnChange
事件以接收通知:
void OnChange(object sender, SqlNotificationEventArgs e)
而且在代码中:
SqlCommand cmd = ...
cmd.Notification = null;
SqlDependency dependency = new SqlDependency(cmd);
dependency.OnChange += OnChange;
它使用Service Broker
(一种基于消息的通信平台)来接收来自数据库引擎的消息。
SqlSependency
。那么,在SQL Azure数据更改或插入新数据时,有没有比这个更好的方法来获取通知呢? - Shaiju T通常,你会使用Service Broker
这是触发器 -> 队列 -> 应用程序(s)
另外,在查看其他答案后编辑:
FYI: "Query Notifications" 建立在 Service broker 之上
编辑2:
更多链接
SqlSependency
,所以有没有比这个更好的方法来在SQL Azure数据更改或插入新数据时获取通知? - Shaiju T使用SqlTableDependency。它是一个C#组件,当记录更改时会触发事件。 您可以在此处找到其他详细信息:https://github.com/christiandelbianco/monitor-table-change-with-sqltabledependency
与.NET SqlDependency相似,但SqlTableDependency会引发包含修改/删除或更新的数据库表值的事件:
string conString = "data source=.;initial catalog=myDB;integrated security=True";
using(var tableDependency = new SqlTableDependency<Customers>(conString))
{
tableDependency.OnChanged += TableDependency_Changed;
tableDependency.Start();
Console.WriteLine("Waiting for receiving notifications...");
Console.WriteLine("Press a key to stop");
Console.ReadKey();
}
...
...
void TableDependency_Changed(object sender, RecordChangedEventArgs<Customers> e)
{
if (e.ChangeType != ChangeType.None)
{
var changedEntity = e.Entity;
Console.WriteLine("DML operation: " + e.ChangeType);
Console.WriteLine("ID: " + changedEntity.Id);
Console.WriteLine("Name: " + changedEntity.Name);
Console.WriteLine("Surname: " + changedEntity.Surname);
}
}
使用SqlDependency类时要小心 - 它存在内存泄漏的问题。
只需使用跨平台、.NET 3.5、.NET Core兼容且开源的解决方案 - SqlDependencyEx。您可以获取通知以及已更改的数据(可以通过通知事件对象中的属性访问它)。您还可以单独或一起跟踪DELETE\UPDATE\INSERT操作。
以下是使用SqlDependencyEx的示例,非常简单:
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);
请点击链接查看详细信息。此组件已在许多企业级应用程序中进行了测试,并被证明是可靠的。希望这可以帮到您。
SqlDependency不会监视数据库,它监视您指定的SqlCommand,因此,如果您尝试在一个项目中插入值并在另一个项目中捕获该事件,它将无法工作,因为事件来自于第一个项目的SqlCommand而不是数据库,因为当您创建SqlDependency时,您将其链接到一个SqlCommand,只有在使用该项目的命令时才会创建Change事件。
自从 SQL Server 2005 开始,你可以选择使用查询通知,ADO.NET 可以利用这一特性,详情请见http://msdn.microsoft.com/en-us/library/t9x04ed2.aspx
1-创建名为TestNotification
的新数据库
2-添加名为Customers
的新表,字段:Id
,Name
,Family
3-您应启用ServiceBroker
4-在SQL中运行此代码
ALTER DATABASE [TestNotification] SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE
5- 创建新项目 c# consoleApp
6- 在 nuget
中安装 SqlTableDependency
库
7- 创建名为 Customer
的类
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string Family { get; set; }
}
在 Program.cs
文件中编写以下代码:
static void Main(string[] args)
{
var connectionString = "data source=.;initial catalog=TestNotification;integrated security=true;";
using (var tableDependecy = new SqlTableDependency<Customer>(connectionString, "Customers"))
{
tableDependecy.OnChanged += TableDependency_Changed;
tableDependecy.OnError += TableDependency_OnError;
tableDependecy.Start();
Console.WriteLine("Waiting");
Console.ReadKey();
tableDependecy.Stop();
}
}
static void TableDependency_Changed(object sender, RecordChangedEventArgs<Customer> e)
{
Console.WriteLine(Environment.NewLine);
if (e.ChangeType != ChangeType.None)
{
var changeEntity = e.Entity;
Console.WriteLine("ChangeType: " + e.ChangeType);
Console.WriteLine("Id: " + changeEntity.Id);
Console.WriteLine("Name: " + changeEntity.Name);
Console.WriteLine("Id: " + changeEntity.Family);
Console.WriteLine(Environment.NewLine);
}
}
static void TableDependency_OnError(object sender, ErrorEventArgs e)
{
Console.WriteLine(e.Message);
}
这并不完全是一条通知,但标题中提到了监控,它可以适用于这种情况。
使用SQL Server时间戳列可以轻松查看在查询之间仍然存在的任何更改。
在我看来,SQL Server时间戳列类型的命名非常糟糕,因为它与时间无关,它是一个数据库范围内的值,在任何插入或更新时自动增加。您可以在您想要的表中选择Max(timestamp),或者从刚刚插入的行中返回时间戳,然后只需选择 where timestamp > storedTimestamp,这将给出所有在这些时间之间已更新或插入的结果。
由于它是一个数据库范围内的值,因此您可以使用存储的时间戳来检查自上次检查/更新存储的时间戳以来是否有数据写入任何表。