2012-04-18 7 views
0

SqlNotificationEventデータベース内の単一の挿入に対しても複数回通知します。SqlNotificationEventはデータベース内の単一の挿入でも複数回通知します

テーブル内の単一の挿入/更新/削除の場合でも、イベントは何度かe.Type == SqlNotificationType.Changeで通知されますが、これはなぜ起こるのでしょうか。それは、テーブルの単一の変更に対して1回だけ通知する必要があります。

static class Program 
{ 
    private static string mStarterConnectionString = "Data Source=localhost;Database=SqlDependencyTest;Persist Security Info=false;Integrated Security=false;User Id=startUser;Password=startUser"; 
    private static string mSubscriberConnectionString = "Data Source=localhost;Database=SqlDependencyTest;Persist Security Info=false;Integrated Security=false;User Id=subscribeUser;Password=subscribeUser"; 
    public const string CACHE_KEY = "APPCACHEKEY"; 

    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     // Starting the listener infrastructure... 
     SqlDependency.Start(mStarterConnectionString); 

     // Registering for changes... 
     RegisterForChanges(); 

     Application.Run(new SqlCache()); 

     // Quitting... 
     SqlDependency.Stop(mStarterConnectionString); 
    } 

    public static DataTable RegisterForChanges() 
    { 
     DataTable dataTable = new DataTable(); 

     // Connecting to the database using our subscriber connection string and 
     // waiting for changes... 
     SqlConnection oConnection = new SqlConnection(mSubscriberConnectionString); 
     oConnection.Open(); 
     try 
     { 
      using (SqlCommand oCommand = new SqlCommand("dbo.GetUsers", oConnection)) 
      //using (SqlCommand oCommand = new SqlCommand("SELECT ID, Name FROM dbo.Users", oConnection)) 
      { 
       oCommand.CommandType = CommandType.StoredProcedure; 
       SqlDependency oDependency = new SqlDependency(oCommand); 
       oDependency.OnChange += new OnChangeEventHandler(OnNotificationChange); 
       using (SqlDataAdapter adapter = new SqlDataAdapter(oCommand)) 
        adapter.Fill(dataTable); 
      } 

      AppMain.Cache.Insert(CACHE_KEY, dataTable, null, Cache.NoAbsoluteExpiration, TimeSpan.FromSeconds(60)); 
     } 
     finally 
     { 
      oConnection.Close(); 
     } 
     return dataTable; 
    } 

    public static void OnNotificationChange(object caller, SqlNotificationEventArgs e) 
    { 
     if (e.Type == SqlNotificationType.Change) 
      RegisterForChanges(); 
    } 

答えて

0

あなたはSqlNotificationEventArgsオブジェクトのSqlNotificationInfoオブジェクトを使用して、それが挿入、更新であるかどうかをチェックしたり、削除し、残りの部分を無視することができます。

public static void OnNotificationChange(object caller, SqlNotificationEventArgs e) 
{ 
    if (e.Type == SqlNotificationType.Change && (e.Info == SqlNotificationInfo.Insert || e.Info == SqlNotificationInfo.Delete || e.Info == SqlNotificationInfo.Update)) 
    { 
     SqlDependency dependency =(SqlDependency)sender; 
     dependency.OnChange -= OnNotificationChange; 
     RegisterForChanges(); 
    } 
} 
+0

パブリック静的ボイドOnNotificationChange(オブジェクトの発信者、SqlNotificationEventArgs E){IF(e.Type == SqlNotificationType.Change &&(e.Info == SqlNotificationInfo.Insert || e.Info == SqlNotificationInfo。削除|| e.Info == SqlNotificationInfo.Update))RegisterForChanges();}私は行っていますe.Typeは "Change"を表示し、e.Infoは "Insert"を表示します。もし誰かがこの問題を知っていれば、私にしてください。 – Shivu

+0

@ Shivu回答が更新されました。チェックしてください – Damith

-1

私は質問に記載されているのと同じ問題がありました。私は、問題はあなたがRegisterForChanges()using (SqlCommand oCommand = new SqlCommand("dbo.GetUsers", oConnection))を持っているのと同じように、複数のSqlCommandのインスタンスを(作成から生じたことを正確に特定することができました。

私はSqlCommandSqlConnectionオブジェクトへのインスタンスの参照を宣言するためにコードを変更し、そして唯一の新しいSqlDependencyインスタンスをインスタンス化RegisterForChanges()方法。

void RegisterForChanges() 
{ 
    _sqlCommand.Notification = null; 
    _sqlConnection.Open(); 
    SqlDependency dependency = new SqlDependency(_sqlCommand); 
    dependency.OnChange += dependency_OnChange; 
    _sqlCommand.ExecuteNonQuery(); // or ExecuteReader and parse the results, etc 
    _sqlConnection.Close(); 
} 
関連する問題