remarks generate example c# wpf sqldependency

generate - params comments c#



SQLDependency_OnChange-Event dispara solo una vez (6)

Después de que los cambios ocurrieron en la base de datos la primera vez, debe ejecutar el comando nuevamente y volver a suscribirse al evento.

El siguiente código está funcionando para mí.

class Program { static string connectionString = "Server=.;Database=test_sql_dependency;Integrated Security=True;"; static void Main(string[] args) { // 1. create database // 2. enable service broker by executing this sql command on the database. // alter database test_sql_dependency set enable_broker // 3. start sql dependency, for some sql server connection string or with queue if you want. //var queueName = "myFirstQueue"; //SqlDependency.Start(connectionString, queueName); SqlDependency.Start(connectionString); // complete the rest of the steps in seperate method to be able to call it again when you need to // re-subscribe to the event again, becuase by default it will be executed only one time RegisterSqlDependency(); Console.WriteLine("Listening to database changes..."); Console.ReadLine(); } static void RegisterSqlDependency() { using (SqlConnection connection = new SqlConnection(connectionString)) { if (connection.State != System.Data.ConnectionState.Open) { connection.Open(); } // 4. create a sql command // you can''t say select *, and also you have to specefy the db owner (dbo.) SqlCommand command = new SqlCommand("select Id, Name from dbo.Employee", connection); // 5. create dependency and associtate it to the sql command SqlDependency dependency = new SqlDependency(command); // 6. subscribe to sql dependency event dependency.OnChange += new OnChangeEventHandler(OnDependencyChange); // 7. execute the command using (SqlDataReader reader = command.ExecuteReader()) { } } } static void OnDependencyChange(object sender, SqlNotificationEventArgs e) { var InsertOrUpdateOrDelte = e.Info; //-----------------------------Finally------------------------- // after you knew that there is a change happened // you have to unsubscribe the event and execute the command again and then re-subscribe to the event // 1. unsubscribe the event SqlDependency dependency = sender as SqlDependency; dependency.OnChange -= OnDependencyChange; // 2. re-subscribe to the event and execute the command again RegisterSqlDependency(); } }

Estoy trabajando con SQLDependency para notificarme si hay algún cambio en la base de datos. Después de la puesta en marcha del programa funciona bien. Cuando hago un primer cambio el evento se dispara. Wohoo ... eso es genial. Pero si hago un segundo cambio, el evento no se dispara de nuevo. He buscado en toda la web, pero no he encontrado nada sobre ESTE problema. Solo se encontraron problemas donde el evento OnChange se dispara en un bucle. ¿Alguien puede ayudarme?

Aquí un pequeño código:

private void GetStates() { if (!DoesUserHavePermission()) return; SqlDependency.Stop(con); SqlDependency.Start(con); using (SqlConnection cn = new SqlConnection(con)) { using (SqlCommand cmd = cn.CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = "SELECT Bla, Bla2, ..FROM dbo.[BLA3]" cmd.Notification = null; cmd.Dispose(); SqlDependency dep = new SqlDependency(cmd); dep.OnChange += new OnChangeEventHandler(dep_OnChange); cn.Open(); using (SqlDataReader dr = cmd.ExecuteReader()) { state.Clear(); //In this Case "state" is a List<string> while (dr.Read()) { state.Add(dr.GetString(0) + "|" + dr.GetInt32(3)); } dr.Dispose(); dr.Close(); } } } }

mi evento OnChange se ve así:

private void dep_OnChange(object sender, SqlNotificationEventArgs e) { SqlDependency dep = sender as SqlDependency; dep.OnChange -= this.dep_OnChange; using (SqlConnection cn = new SqlConnection(con)) { using (SqlCommand cmd = cn.CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = "SELECT Bla, Bla2, ..FROM dbo.[BLA3]"; cmd.Notification = null; if (e.Type == SqlNotificationType.Change) { if (cn.State != ConnectionState.Open) { cn.Open(); } using (SqlDataReader dr = cmd.ExecuteReader()) { state.Clear(); // Clear and Refill the stringlist "state" while (dr.Read()) { state.Add(dr.GetString(0) + "|" + dr.GetInt32(3)); } } } cn.Close(); } } this.GetStates(); //to go ahead and wait for a new change }

¿Dónde está el problema?


En GetStates ():

SqlDependency.Stop(con); SqlDependency.Start(con);

estas líneas deben ejecutarse solo al registrar la dependencia de SQL por primera vez.

Limítelos cuando llame al método desde el evento OnChange.


En su private void dep_OnChange(object sender, SqlNotificationEventArgs e) después de cancelar la suscripción del evento dep_OnChange , debe llamar nuevamente al private void GetStates() para inicializar nuevamente el evento dep.OnChange .


Mira mi amigo

dep.OnChange -= this.dep_OnChange;

has desencadenado tu evento; lo cual no es verdad; simplemente borre esta línea;


No estoy seguro de si ese es tu problema, pero eliminas el comando justo después de haberlo creado:

using (SqlCommand cmd = cn.CreateCommand()) { ... cmd.Dispose();

Parece un error.


También me estaba encontrando en este problema. Debe crear una nueva entidad SqlDependency (después de cancelar la suscripción de la existente del evento OnChange) y luego ejecutar un nuevo comando ExecuteReader. Tengo la idea de este post:

http://www.codeproject.com/Articles/12335/Using-SqlDependency-for-data-change-events

Esto generalmente tiene sentido, ya que una vez que haya sido notificado de un cambio, normalmente querrá volver a consultar los datos.