2012-04-18 82 views
0

SqlNotificationEvent多次通知数据库中甚至是单次插入。SqlNotificationEvent通知多次,即使在数据库中单次插入也是如此

即使对于表单中的单个插入/更新/删除,事件也会通过e.Type == SqlNotificationType.Change多次通知,任何人都可以帮助解释为什么会发生这种情况。它应该只通知一次表中的单个更改。

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){如果(e.Type == SqlNotificationType.Change &&(e.Info == SqlNotificationInfo.Insert || e.Info == SqlNotificationInfo。删除|| e.Info == SqlNotificationInfo.Update))RegisterForChanges();}我已经完成上面的变化,实际上e.Type显示“更改”和e.Info显示“插入”,在表中插入一行时多次。如果有人知道这个问题,请告诉我。 – Shivu 2012-04-18 08:51:22

+0

@Shivu回答更新。请检查 – Damith 2012-04-18 09:36:27

-1

我遇到了与问题中所述相同的问题。我能够确定,这个问题是由于创建多个SqlCommand实例(类似于你怎么有using (SqlCommand oCommand = new SqlCommand("dbo.GetUsers", oConnection))RegisterForChanges()

我改变了代码实例引用申报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(); 
}