2016-12-10 2 views
0

Ich bin neu im Konzept der Abfragebenachrichtigungen mit SQL Server und es wird einige Zeit dauern, bis ich mich eingehender damit beschäftige.SqlDependency löst kein OnChange-Ereignis aus, wenn Dataset geändert wird

Mein Ziel ist es, eine Windows-Dienstanwendung zu erstellen, die benachrichtigt wird, wenn eine Änderung an einer SQL Server-Tabelle vorgenommen wurde. Ich folgte this Leitfaden, der hilfreich war, um mich zu beginnen.

Ich bin jedoch nicht in der Lage, das erwartete Ergebnis zu erhalten. Die OnStart() Methode in meinem Windows-Dienst App sieht so aus:

protected override void OnStart(string[] args) 
{ 
     eventLog1.WriteEntry("Service Started"); 

     serviceRun = false; 

     SqlClientPermission perm = new SqlClientPermission(System.Security.Permissions.PermissionState.Unrestricted); 

     try 
     { 
      perm.Demand(); 
      eventLog1.WriteEntry("permission granted"); 
     } 
     catch (System.Exception) 
     { 
      eventLog1.WriteEntry("permission denied"); 
     } 

     try 
     { 
      connstr = "Data Source=THSSERVER-LOCAL;Initial Catalog=ET;User ID=mujtaba;Password=ths123"; 

      connection = new SqlConnection(connstr); 

      SqlCommand command = new SqlCommand("select * from dbo.Customer_FileUploads", connection); 

      // Create a dependency and associate it with the SqlCommand. 
      SqlDependency dependency = new SqlDependency(command); 

      // Maintain the reference in a class member. 
      // Subscribe to the SqlDependency event. 
      dependency.OnChange += Dependency_OnChange; 

      SqlDependency.Start(connstr); 

      connection.Open(); 

      // Execute the command. 
      using (SqlDataReader reader = command.ExecuteReader()) 
      { 
       if (reader.HasRows) 
       { 
        while (reader.Read()) 
        { 
         //eventLog1.WriteEntry("reading data"); 
        } 
       } 
       else 
       { 
        eventLog1.WriteEntry("No rows found."); 
       } 
       reader.Close(); 
      } 
     } 
     catch (Exception e) 
     { 
      eventLog1.WriteEntry("Error Message: " + e.Message); 
     } 
} 

Die Veranstaltung SqlDependency abonniert wird, sieht so aus:

private void Dependency_OnChange(object sender, SqlNotificationEventArgs e) 
{ 
    // Handle the event. 
    eventLog1.WriteEntry("data changed"); 
} 

Die OnStop() Methode sieht so aus:

protected override void OnStop() 
{ 
     SqlDependency.Stop(connstr); 
     connection.Close(); 
     eventLog1.WriteEntry("In onStop."); 
} 

Ich habe ENABLE_BROKER auf True in meiner Datenbank festgelegt. Das Endergebnis ist, der Dienst und die folgenden Protokolle erstellt werden:

"Service Started" 
"permission granted" 
"data changed" 

jedoch, wenn ich neue Daten in die Tabelle einfügen, das OnChange() Ereignis nicht abfeuert und kein neues Protokoll erstellt. Auch wenn ich den Dienst erneut stoppe und starte, wird die OnChange() ausgelöst, obwohl keine neuen Daten eingefügt wurden.

Kann jemand mir helfen, den Prozess zu verstehen?

Antwort

1

Die SqlDependency wird entfernt, nachdem das Ereignis ausgelöst wurde, sodass Sie den Befehl erneut mit der Abhängigkeit ausführen müssen. Im Folgenden finden Sie ein Beispiel für eine Konsolenanwendung, die erneut abonniert wird, sofern die Benachrichtigung nicht auf einen Fehler zurückzuführen ist.

using System; 
using System.Data; 
using System.Data.SqlClient; 

namespace SqlDependencyExample 
{ 
    class Program 
    { 

     static string connectionString = @"Data Source=.;Initial Catalog=YourDatabase;Application Name=SqlDependencyExample;Integrated Security=SSPI"; 

     static void Main(string[] args) 
     { 

      SqlDependency.Start(connectionString); 

      getDataWithSqlDependency(); 

      Console.WriteLine("Waiting for data changes"); 
      Console.WriteLine("Press enter to quit"); 
      Console.ReadLine(); 

      SqlDependency.Stop(connectionString); 

     } 

     static DataTable getDataWithSqlDependency() 
     { 

      using (var connection = new SqlConnection(connectionString)) 
      using (var cmd = new SqlCommand("SELECT Col1, Col2, Col3 FROM dbo.MyTable;", connection)) 
      { 

       var dt = new DataTable(); 

       // Create dependency for this command and add event handler 
       var dependency = new SqlDependency(cmd); 
       dependency.OnChange += new OnChangeEventHandler(onDependencyChange); 

       // execute command to get data 
       connection.Open(); 
       dt.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection)); 

       return dt; 

      } 

     } 

     // Handler method 
     static void onDependencyChange(object sender, 
      SqlNotificationEventArgs e) 
     { 

      Console.WriteLine($"OnChange Event fired. SqlNotificationEventArgs: Info={e.Info}, Source={e.Source}, Type={e.Type}."); 

      if ((e.Info != SqlNotificationInfo.Invalid) 
       && (e.Type != SqlNotificationType.Subscribe)) 
      { 
       //resubscribe 
       var dt = getDataWithSqlDependency(); 

       Console.WriteLine($"Data changed. {dt.Rows.Count} rows returned."); 
      } 
      else 
      { 
       Console.WriteLine("SqlDependency not restarted"); 
      } 

     } 


    } 
} 
+0

Das funktionierte für mich – psyoptica

Verwandte Themen