usar sistema notificaciones example ejemplo detectar datos con como cambios c# sql-server visual-studio-2005 notifications

c# - sistema - ¿Cómo puedo notificar a mi programa cuando la base de datos se ha actualizado?



sistema de notificaciones c# (5)

Tengo un programa C # que consulta la base de datos de SQL Server para algunos valores.

Actualmente, la aplicación consulta la base de datos cada minutos para asegurarse de que la tabla esté actualizada.

Lo que me gustaría hacer es que la consulta solo se realice cuando la base de datos ha sido modificada / actualizada. ¿Cómo notifico mi programa cuando algo se ha actualizado en la base de datos?

Gracias


Si está en SQL Server 2005 y superior, puede considerar usar el objeto SqlDependency.

Representa una dependencia de notificación de consulta entre una aplicación y una instancia de SQL Server 2005.

Una aplicación puede crear un objeto SqlDependency y registrarse para recibir notificaciones a través del controlador de eventos OnChangeEventHandler.

Consulte este enlace en MSDN para obtener más información

Sin embargo, tenga en cuenta la advertencia que MS pone en contra de su uso. Se recomienda tener una capa de almacenamiento en caché y luego usar SQLDependency en coordinación con esa capa.

SqlDependency fue diseñado para ser utilizado en ASP.NET o servicios de nivel medio donde hay un número relativamente pequeño de servidores que tienen dependencias activas contra la base de datos. No fue diseñado para su uso en aplicaciones cliente, donde cientos o miles de computadoras cliente tendrían objetos SqlDependency configurados para un solo servidor de base de datos.


Si por "actualizaciones a la base de datos" te refieres a cualquier actualización de cualquier aplicación, no tienes suerte: no es factible.

Sin embargo, si te refieres a los cambios realizados por tu aplicación, es fácil: cada vez que actualizas el aumento y el evento de DB y los manejadores responden al evento.


Para recibir una notificación cuando se actualiza algún registro, evite que la aplicación consulte la tabla que utiliza el componente TableDependency (en su caso específico SqlTableDependency ). Aquí hay un ejemplo:

public partial class Window1 : Window { private IList<Stock> _stocks; private readonly string _connectionString = "data source=.;initial catalog=myDB;integrated security=True"; private readonly SqlTableDependency<Stock> _dependency; public Window1() { this.InitializeComponent(); this.McDataGrid.ItemsSource = LoadCollectionData(); this.Closing += Window1_Closing; var mapper = new ModelToTableMapper<Stock>(); mapper.AddMapping(model => model.Symbol, "Code"); _dependency = new SqlTableDependency<Stock>(_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<Stock> 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<Stock> LoadCollectionData() { _stocks = new List<Stock>(); 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; }

El controlador de eventos se activa para cada operación INSERT UPDATE o DELETE realizada en la tabla, informándole el valor modificado. Entonces, en caso de que esté interesado en mantener actualizada su tabla de datos C #, puede obtener los datos recientes del manejador de eventos.


Lo que me gustaría poder hacer es que la consulta solo se realice cuando se haya cambiado / actualizado la base de datos. ¿Cómo notifico mi programa cuando algo se actualizó en la base de datos?

No hay ningún medio para que la base de datos envíe notificaciones a la aplicación. La aplicación necesita sondear la base de datos para buscar actualizaciones y luego tratar las actualizaciones de manera apropiada.


La base de datos de votación no es una solución muy elegante.

SqlDependency de ADO.NET será útil en su caso. No usa sondeo sino mecanismo de notificación. Las notificaciones las proporciona Service Broker en su base de datos, por lo que deberá habilitar este servicio en su base de datos. El evento OnChange se generará cuando se cambien las tablas especificadas (actualizar, eliminar, insertar ...)

Aquí hay un ejemplo de cómo usar 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); }

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

Aquí le mostramos cómo habilitar Service Broker (tenga en cuenta que tendrá exclusividad en la base de datos para hacerlo, lo mejor es hacerlo después de reiniciar el servidor sql): http://blogs.sftsrc.com/stuart/archive/2007/06/ 13 / 42.aspx (Enlace roto)

Posible enlace alternativo: http://technet.microsoft.com/en-us/library/ms166086(v=sql.105).aspx