数据库更新后如何通知我的程序?

我有一个C#程序,它在SQL Server数据库中查询某些值。

目前,应用程序每分钟查询一次数据库,以确保该表是最新的。

我希望能够做的是只在数据库被更改/更新时才进行查询。 如何在数据库中更新某些内容后如何通知我的程序?

谢谢

轮询数据库解决方案不是很优雅。

来自ADO.NET的SqlDependency对您的情况很有用。 它不使用轮询而是使用通知机制。 这些通知由Service Broker在您的数据库中提供,因此需要在您的数据库中启用此服务。 当指定的表更改(更新,删除,插入..)时, OnChange事件将引发

以下是如何使用SqlDependency的示例:

 void Initialization() { // Create a dependency connection. SqlDependency.Start(connectionString, queueName); } void SomeMethod() { // Assume connection is an open SqlConnection. // Create a new SqlCommand object. using (SqlCommand command=new SqlCommand( "SELECT ShipperID, CompanyName, Phone FROM dbo.Shippers", connection)) { // Create a dependency and associate it with the SqlCommand. SqlDependency dependency=new SqlDependency(command); // Maintain the refence in a class member. // Subscribe to the SqlDependency event. dependency.OnChange+=new OnChangeEventHandler(OnDependencyChange); // Execute the command. using (SqlDataReader reader = command.ExecuteReader()) { // Process the DataReader. } } } // Handler method void OnDependencyChange(object sender, SqlNotificationEventArgs e ) { // Handle the event (for example, invalidate this cache entry). } void Termination() { // Release the dependency. SqlDependency.Stop(connectionString, queueName); } 

来自http://msdn.microsoft.com/en-us/library/62xk7953.aspx

以下是如何启用Service Broker(请注意,您将在数据库上具有独占性来执行此操作 – 最好在重新启动sql server之后执行此操作): http//blogs.sftsrc.com/stuart/archive/2007/06/ 13 / 42.aspx (断链)

可能的替代链接: http : //technet.microsoft.com/en-us/library/ms166086(v = sql.105).aspx

如果您使用的是SQL Server 2005及更高版本,则可以考虑使用SqlDependency对象。

它表示应用程序与SQL Server 2005实例之间的查询通知依赖关系。

应用程序可以创建SqlDependency对象并注册以通过OnChangeEventHandler事件处理程序接收通知。

有关详细信息,请参阅MSDN上的此链接

但是,请注意MS对其使用的警告。 建议使用缓存层,然后与该层协调使用SQLDependency。

SqlDependency旨在用于ASP.NET或中间层服务,其中存在相对较少数量的服务器,这些服务器具有对数据库的活动依赖性。 它不是设计用于客户端应用程序,其中数百或数千台客户端计算机将为单个数据库服务器设置SqlDependency对象。

要在更新某些记录时获取通知,请避免应用程序查询您使用TableDependency组件的表(在您的特定情况下为SqlTableDependency )。 这是一个例子:

 public partial class Window1 : Window { private IList _stocks; private readonly string _connectionString = "data source=.;initial catalog=myDB;integrated security=True"; private readonly SqlTableDependency _dependency; public Window1() { this.InitializeComponent(); this.McDataGrid.ItemsSource = LoadCollectionData(); this.Closing += Window1_Closing; var mapper = new ModelToTableMapper(); mapper.AddMapping(model => model.Symbol, "Code"); _dependency = new SqlTableDependency(_connectionString, "Stocks", mapper); _dependency.OnChanged += _dependency_OnChanged; _dependency.OnError += _dependency_OnError; _dependency.Start(); } private void Window1_Closing(object sender, System.ComponentModel.CancelEventArgs e) { _dependency.Stop(); } private void _dependency_OnError(object sender, TableDependency.EventArgs.ErrorEventArgs e) { throw e.Error; } private void _dependency_OnChanged( object sender, TableDependency.EventArgs.RecordChangedEventArgs e) { if (_stocks != null) { if (e.ChangeType != ChangeType.None) { switch (e.ChangeType) { case ChangeType.Delete: _stocks.Remove(_stocks.FirstOrDefault(c => c.Symbol == e.Entity.Symbol)); break; case ChangeType.Insert: _stocks.Add(e.Entity); break; case ChangeType.Update: var customerIndex = _stocks.IndexOf( _stocks.FirstOrDefault(c => c.Symbol == e.Entity.Symbol)); if (customerIndex >= 0) _stocks[customerIndex] = e.Entity; break; } this.McDataGrid.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() => { this.McDataGrid.Items.Refresh(); })); } } } private IEnumerable LoadCollectionData() { _stocks = new List(); using (var sqlConnection = new SqlConnection(_connectionString)) { sqlConnection.Open(); using (var sqlCommand = sqlConnection.CreateCommand()) { sqlCommand.CommandText = "SELECT * FROM [Stocks]"; using (var sqlDataReader = sqlCommand.ExecuteReader()) { while (sqlDataReader.Read()) { var code = sqlDataReader .GetString(sqlDataReader.GetOrdinal("Code")); var name = sqlDataReader .GetString(sqlDataReader.GetOrdinal("Name")); var price = sqlDataReader .GetDecimal(sqlDataReader.GetOrdinal("Price")); _stocks.Add(new Stock { Symbol = code, Name = name, Price = price }); } } } } return _stocks; } 

在表上执行的每个INSERT UPDATE或DELETE操作都会触发事件处理程序,并向您报告修改后的值。 因此,如果您有兴趣让C#Datatable保持最新,那么您可以从事件处理程序中获取新数据。

我希望能够做的是只在数据库被更改/更新时才进行查询。当数据库中的某些内容更新时,我如何通知我的程序。

数据库没有任何方法将通知推送到应用程序。 应用程序需要轮询数据库以检查更新,然后适当地处理更新。

如果通过“对数据库的更新”表示任何应用程序的任何更新,那么你运气不好:它不可行。

但是,如果您的意思是应用程序所做的更改,则很容易:每次更新数据库引发和事件并让处理程序响应事件。