2011-05-12 15 views
7

this MSDN page'dan bir örnek çektim ve onu oldukça fazla verbatim kullandım. Kod çalıştırıldığında düzgün bir şekilde derlenir, ancak changeCount artışları, döndürülmüş verilerde gerçekten bir değişiklik olup olmadığına bakılmaksızın sonsuzdur. Gerçekte bir değişiklik olduğunda oluştu dataGridView1 değişikliği doğru olarak yansıtır. Neden SqlDependency benim açımdan görünüşe göre hiçbir değişiklik yapılmasa bile bir döngüde ateş gibi görünüyor?SqlDependency kullanımı sabit güncelleştirmelerle sonuçlanır

#region Using directives 
using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Data.SqlClient; 
using System.Drawing; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.Security.Permissions; 
using System.Text; 
using System.Windows.Forms; 
#endregion 

namespace PreAllocation_Check 
{ 
    public partial class Form1 : Form 
    { 
     int   changeCount = 0; 
     const string tableName = "MoxyPosition"; 
     const string statusMessage = "Last: {0} - {1} changes."; 
     DataSet  dataToWatch = null; 
     SqlConnection MoxyConn = null; 
     SqlCommand SQLComm = null; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      if (CanRequestNotifications()) 
      { 
       SqlDependency.Start(GetConnectionString()); 

       if (MoxyConn == null) 
        MoxyConn = new SqlConnection(GetConnectionString()); 

       if (SQLComm == null) 
       { 
        SQLComm = new SqlCommand(GetSQL(), MoxyConn); 

        SqlParameter prm = new SqlParameter("@Quantity", SqlDbType.Int); 
        prm.Direction = ParameterDirection.Input; 
        prm.DbType = DbType.Int32; 
        prm.Value = 100; 
        SQLComm.Parameters.Add(prm); 
       } 

       if (dataToWatch == null) 
        dataToWatch = new DataSet(); 

       GetData(); 
      } 
     } 

     private void Form1_FormClosed(object sender, FormClosedEventArgs e) 
     { 
      SqlDependency.Stop(GetConnectionString()); 
      if (MoxyConn != null) 
       MoxyConn.Close(); 
     } 

     private bool CanRequestNotifications() 
     { 
      try 
      { 
       SqlClientPermission SQLPerm = new SqlClientPermission(PermissionState.Unrestricted); 
       SQLPerm.Demand(); 
       return true; 
      } 
      catch 
      { 
       return false; 
      } 
     } 

     private string GetConnectionString() 
     { 
      return "server=***;database=***;user id=***;password=***"; 
     } 

     private void GetData() 
     { 
      dataToWatch.Clear(); 
      SQLComm.Notification = null; 
      SqlDependency SQLDep = new SqlDependency(SQLComm); 
      SQLDep.OnChange += new OnChangeEventHandler(SQLDep_OnChange); 

      using (SqlDataAdapter adapter = new SqlDataAdapter(SQLComm)) 
      { 
       adapter.Fill(dataToWatch, tableName); 
       dataGridView1.DataSource = dataToWatch; 
       dataGridView1.DataMember = tableName; 
      } 
     } 

     private string GetSQL() 
     { 
      return "SELECT PortID, CONVERT(money, SUM(PreAllocPos), 1) AS PreAllocation, CONVERT(money, SUM(AllocPos), 1) AS Allocation, CONVERT(money, SUM(PreAllocPos) - SUM(AllocPos), 1) AS PreLessAlloc " + 
        "FROM MoxyPosition " + 
        "WHERE CONVERT(money, PreAllocPos, 1) <> CONVERT(money, AllocPos, 1) " + 
        "GROUP BY PortID " + 
        "ORDER BY PortID ASC;"; 
     } 

     void SQLDep_OnChange(object sender, SqlNotificationEventArgs e) 
     { 
      ISynchronizeInvoke i = (ISynchronizeInvoke)this; 

      if (i.InvokeRequired) 
      { 
       OnChangeEventHandler tempDelegate = new OnChangeEventHandler(SQLDep_OnChange); 
       object[] args = { sender, e }; 
       i.BeginInvoke(tempDelegate, args); 
       return; 
      } 

      SqlDependency SQLDep = (SqlDependency)sender; 
      SQLDep.OnChange -= SQLDep_OnChange; 

      changeCount++; 
      DateTime LastRefresh = System.DateTime.Now; 
      label1.Text = String.Format(statusMessage, LastRefresh.TimeOfDay, changeCount); 

      GetData(); 
     } 
    } 
} 

Düzenleme: İşte

kaynağıdır Bu veritabanı Şu anda Broker Servisi sağladı vermez buna karşı çalıştırmak istediğiniz fazlalaştı ve bu yüzden yedeklenen kodumu test etmek benim veritabanını hedefleyin ve yeni bir adla geri yükleyin, daha sonra ALTER DATABASE my_db_name SET ENABLE_BROKER'u çalıştırın. Bütün testlerim bu alternatif veri tabanından geldi, yani bunun tek kullanıcısıyım.

cevap

0

Bunun bir cevabı yok, ama burada kurallar en az birini kırdınız: İki parçalı tablo adlarını kullanmak için başarısız http://msdn.microsoft.com/en-us/library/aewzkxxh.aspx

. MoxyPosition öğesini dbo.MoxyPosition olarak değiştirin ve yukarıda açıklanan kuralları gözden geçirin. Umarım yardımcı olur, ama bir şey bana burada başka bir şey olduğunu söyler.

1

Benzer bir sorunla karşılaştım. Güncellemenin sürekli olarak SELECT * FROM dbo.MyTable yapmasına neden oluyor. SELECT Id, Column1, Column2 FROM dbo.MyTable ile ilgili sorun, sorunu giderdi.

Sorunuzda * kullanıyorsunuz gibi görünmüyor, ancak soruna hala sahip olup olmadığınızı görmek için sorgunuzu basitleştirmeyi deneyebilirsiniz.

4

Bu eski bir sorudur, ancak sorun, sorgunuzun gereksinimleri karşılamamasıdır.

Kısa cevap: masanın "FROM DBO.MoxyPosition " +

için
eklenti şema adı uzun cevap:

Sen dizinli görünüm yaratmanın olanlara çok benzer bir list of requirements here görebilirsiniz. Bir SQL Bağımlılığı kaydedildiğinde, geçersizse bildirim, geçersiz olduğunu bildirerek hemen tetiklenir. Bunu düşündüğünüzde, bu mantıklıdır, çünkü Visual Studio, SQL Engine için dahili gereksinimlerin neler olduğunu nasıl bilebilir?

SQLDep_OnChange fonksiyonunda nedenine bakmak istiyorsunuz bağımlılığı tetikledi. Nedeni, e değişkeninde (bilgi, kaynak ve tür).olay nesnesinin ilgili ayrıntıları burada bulunabilir:

Gets a value that indicates whether this notification is generated 
because of an actual change, OR BY THE SUBSCRIPTION. 
+0

Çok teşekkürler! Bu cevap beni iki gün boyunca aramaya ve denemeye bıraktı. –

0

bkz: MS describesType mülkiyet nasıl özel durum bildirimi için

ne türü SqlNotificationEventArgs işleyicinizde (aşağıdaki gibi tanımlanmıştır). Eğer yüzlerce kez vurduğunu görürseniz ve her seferinde Tür Abone olsaydı, SQL deyiminiz yanlıştır - diğer kayıtlardaki yönergeleri gör

private void HandleOnChange(object sender, SqlNotificationEventArgs e) 
{ 
... 

var someType = e.Type; /*If it is Subscribe, not Change, then you may have your SQL statement wrong*/ 
... 
} 
İlgili konular