订阅 SQL 表更改的通用实用程序

发布于 2024-11-19 17:09:26 字数 2152 浏览 4 评论 0原文

在互联网上搜索了一段时间后,我发现这段代码会在对数据库进行基于 LINQ 的更改时触发。它仅触发一次,并且不会提及或显示更改/删除/添加的内容,或者对哪个表进行了 CRUD。

static class GlobalNotifications
{
    public static event OnChangeEventHandler OnChange;

    public static void InitializeNotifications(string connectString)
    {
        // Initialize notifications
        SqlDependency.Start(connectString);
        // Create and register a new dependency
        SqlDependency dependency = new SqlDependency();
        dependency.OnChange += new OnChangeEventHandler(NotificationCallback);
        System.Runtime.Remoting.Messaging.CallContext.SetData("MS.SqlDependencyCookie", dependency.Id);
    }

    internal static void NotificationCallback(object o, SqlNotificationEventArgs args)
    {
        OnChange.Invoke(o, args);
    }
}

这就是我使用它的方式:

public partial class Nawa : Form
{
  public Nawa()
  {
    InitializeComponent();
  }

  private void Nawa_Load(object sender, EventArgs e)
  {
    GlobalNotifications.InitializeNotifications("Server=GENISYSSERVER; Trusted_Connection=no;database=Maple_DBv1; user id=sa; password=Wc123Wc123");
    GlobalNotifications.OnChange += new System.Data.SqlClient.OnChangeEventHandler(GlobalNotifications_OnChange);
  }

  void GlobalNotifications_OnChange(object sender, System.Data.SqlClient.SqlNotificationEventArgs e)
  {
    MessageBox.Show("Test");
  }

  private void button1_Click(object sender, EventArgs e)
  {
    using (DataClasses1DataContext dbcontext = new DataClasses1DataContext("Server=GENISYSSERVER; Trusted_Connection=no;database=Maple_DBv1; user id=sa; password=Wc123Wc123")) {
      OrderFood random = dbcontext.OrderFoods.FirstOrDefault(id => id.ID == 10);

      if (random != null) { 
        if (random.MenuID == 4)
          random.MenuID = 1;
        else
          random.MenuID = 4;

        dbcontext.SubmitChanges();
      }
    }
  }
}

有人可以在这方面提供帮助吗?如何获取有关更改内容、更改类型、更改表以及为何仅触发一次的更多详细信息。另外,它怎么能只理解 LINQ 的变化呢?它不会在直接更改等时触发。

参考: 即兴自言自语

After a while of searching the internet, I found this piece of code that triggers upon a LINQ-based change to the Database. It trigger only once and doesn't mention or show what was changed/deleted/added, or what table was CRUDed.

static class GlobalNotifications
{
    public static event OnChangeEventHandler OnChange;

    public static void InitializeNotifications(string connectString)
    {
        // Initialize notifications
        SqlDependency.Start(connectString);
        // Create and register a new dependency
        SqlDependency dependency = new SqlDependency();
        dependency.OnChange += new OnChangeEventHandler(NotificationCallback);
        System.Runtime.Remoting.Messaging.CallContext.SetData("MS.SqlDependencyCookie", dependency.Id);
    }

    internal static void NotificationCallback(object o, SqlNotificationEventArgs args)
    {
        OnChange.Invoke(o, args);
    }
}

This is how I'm using it:

public partial class Nawa : Form
{
  public Nawa()
  {
    InitializeComponent();
  }

  private void Nawa_Load(object sender, EventArgs e)
  {
    GlobalNotifications.InitializeNotifications("Server=GENISYSSERVER; Trusted_Connection=no;database=Maple_DBv1; user id=sa; password=Wc123Wc123");
    GlobalNotifications.OnChange += new System.Data.SqlClient.OnChangeEventHandler(GlobalNotifications_OnChange);
  }

  void GlobalNotifications_OnChange(object sender, System.Data.SqlClient.SqlNotificationEventArgs e)
  {
    MessageBox.Show("Test");
  }

  private void button1_Click(object sender, EventArgs e)
  {
    using (DataClasses1DataContext dbcontext = new DataClasses1DataContext("Server=GENISYSSERVER; Trusted_Connection=no;database=Maple_DBv1; user id=sa; password=Wc123Wc123")) {
      OrderFood random = dbcontext.OrderFoods.FirstOrDefault(id => id.ID == 10);

      if (random != null) { 
        if (random.MenuID == 4)
          random.MenuID = 1;
        else
          random.MenuID = 4;

        dbcontext.SubmitChanges();
      }
    }
  }
}

Can someone help in this regard? How to get more details of what was changed, type of change, Table(s) changed, and why does it fire only once. Also, how can it understand LINQ changes only? It doesn't trigger on direct changes etc.

Reference:
Extemporaneous Mumblings

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初见 2024-11-26 17:09:26

SQLDependency 只会触发一次,您需要在触发后重新创建依赖项。

OnChange 事件触发一次后就会被消耗,因此您需要在触发后再次挂接该事件。

Dan Miser - SqlDependency

我没有任何 C# 代码来演示如何处理有了这个,但我确信一些 VB.NET 应该可以很好地工作,以便您提出自己的解决方案。

Private _permissionsDependency As SqlDependency

Private Sub doSubscribe()
    _permissionsDependency = New SqlDependency(cmd.InnerCommand)
    RemoveHandler _permissionsDependency.OnChange, AddressOf User_OnChange
    AddHandler _permissionsDependency.OnChange, AddressOf User_OnChange
End Sub

Private Sub User_OnChange(ByVal sender As Object, ByVal e As System.Data.SqlClient.SqlNotificationEventArgs)
    If _permissionsDependency IsNot Nothing Then RemoveHandler _permissionsDependency .OnChange, AddressOf User_OnChange

    Select Case e.Info
        Case SqlNotificationInfo.Delete
            RaiseEvent UserDeleted(Me)
        Case SqlNotificationInfo.Update
            populateUser()
            RaiseEvent UserUpdated(Me)
        Case Else
    End Select
End Sub

正如您所看到的,您可以通过查看 e.Info 来了解发生了什么,这将使您知道发生了什么(在我的示例中,我只查找删除和更新)。

A SQLDependency will only fire once, you need to recreate the dependency after it has fired.

The OnChange event fires once and then gets consumed, so you need to hook up the event again after it fires.

Dan Miser - SqlDependency

I don't have any C# code to hand to demonstrate how to deal with this but I'm sure some VB.NET should work well enough for you to come up with your own solution.

Private _permissionsDependency As SqlDependency

Private Sub doSubscribe()
    _permissionsDependency = New SqlDependency(cmd.InnerCommand)
    RemoveHandler _permissionsDependency.OnChange, AddressOf User_OnChange
    AddHandler _permissionsDependency.OnChange, AddressOf User_OnChange
End Sub

Private Sub User_OnChange(ByVal sender As Object, ByVal e As System.Data.SqlClient.SqlNotificationEventArgs)
    If _permissionsDependency IsNot Nothing Then RemoveHandler _permissionsDependency .OnChange, AddressOf User_OnChange

    Select Case e.Info
        Case SqlNotificationInfo.Delete
            RaiseEvent UserDeleted(Me)
        Case SqlNotificationInfo.Update
            populateUser()
            RaiseEvent UserUpdated(Me)
        Case Else
    End Select
End Sub

As you can see you can find out what happened by looking at e.Info, which will allow for you to know what happened (in my example I'm only looking for deletes and updates).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文