轮询数据库更改:SqlDependency,SignalR是好的

时间:2014-03-05 12:55:57

标签: jquery asp.net signalr sqldependency

如果我需要通过sql依赖项和signalr在db中显示更改数据,那将是很好的。假设我的交易表经常被很多人改变。假设在很少的时间内很少有第二个数据发生变化,那么我想知道通知将如何进入sql依赖类?

更改数据是否会在sql依赖类之前排队? 当巨大的流量没有进行更改时,sql依赖类可以处理数据更改吗?

这里我正在阅读一篇关于SqlDependency& amp; SignalR。该链接为 http://techbrij.com/database-change-notifications-asp-net-signalr-sqldependency

我不清楚几件事情。

  1. 如何向IIS提供订阅查询通知权限?
  2. 请参阅本文中的行。
  3. private void dependency_OnChange(object sender, SqlNotificationEventArgs e) {
        JobHub.Show();
    }
    

    当数据发生变化时, dependency_OnChange 事件将会触发,JobHub.Show();正在调用

    JobHub is name of class and not static class so i like to know how anyone can call `JobHub.Show();` from out side ??
    
    1. 什么是GlobalHost类以及何时使用它?
    2. 与文章代码相关的问题。请转到此链接
    3.   

      http://techbrij.com/database-change-notifications-asp-net-signalr-sqldependency

      查看视图中的jquery代码,获取数据并填充表。第一次当页面加载时假设表中存在5条记录,那么5条记录将被传递给jquery代码,它将只显示那5条记录但是当表中的任何现有数据发生变化时会发生什么?

      唯一更改的行将到达客户端,或者所有数据(包括已更改的数据)都将到达客户端?

      如果您说只有更改过的数据会代码,那么只需看一下该链接中的视频即可。它显示在视频数据中逐个更改,更改反映在客户端,但如果您看到jquery代码,它只是先清空表并再次构建表。所以我的问题是,如果数据发生变化,只有变更数据会出现,那么一行应该显示在客户端....我是对的。但在视频中,变化和其他数据也是如此。

      所以请您好好阅读链接文章,然后回答我的问题。感谢

      请指导我。感谢

2 个答案:

答案 0 :(得分:3)

好吧,ManniAT很接近,但不是很明显,这里发生的事情是SQLDependency通知事件是一次性交易。因此,他指出它将第一次开火。您需要删除该处理程序(这可以防止在您对该方法进行后续调用时出现多种情况)并重新添加它以便再次触发它。如果您不想直接从SQLDependency设置方法返回数据,(我建议您不要这样做)当您需要重新建立监听器时,可以调用此方法。

回答: 1)通知触发后,您将调用Hub上的方法来刷新已更改的数据。 SqlDependency Notifications应该尽可能具体,当它触发时你应该已经知道UI的哪个部分需要更新。

2)您没有将Hub设置为静态类,因此在调用show方法之前没有首先实例化类的实例就不能调用类上的方法,在示例中我认为它是静态类所以这就是为什么它有效。将集线器设置为静态类并不是我在这种情况下建议的,我会创建一个单独的集线器跟踪类,就像在这个例子中一样。 http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-server-broadcast-with-signalr-20

3)GlobalHost文件在这种情况下,我认为是你的Global.asax,你可以在那里启动和停止你的SqlDependencies。

对示例的修改:

try
        {
            using (
                var connection =
                    new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
            {
                connection.Open();
                using (SqlCommand command = new SqlCommand(@"SELECT [Id]
                                                                        ,[FName]
                                                                        ,[LName]
                                                                        ,[DOB]
                                                                        ,[Notes]
                                                                        ,[PendingReview] 
                                                       FROM [dbo].[Users]",
                    connection))
                {
                    // Make sure the command object does not already have
                    // a notification object associated with it.
                    command.Notification = null;

                    SqlDependency dependency = new SqlDependency(command);

                    dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);

                    if (connection.State == ConnectionState.Closed)
                        connection.Open();

                    command.ExecuteReader();
                }
            }
        }
        catch (Exception e)
        {
            throw;
        }
    }

private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{   
    SqlDependency dependency = sender as SqlDependency;
    if (dependency != null) dependency.OnChange -= dependency_OnChange;
    //Recall your SQLDependency setup method here.
    SetupDependency();
    JobHub.Show();
}

我希望这会对你有所帮助!如果您还有其他问题,请与我们联系。

答案 1 :(得分:0)

SQL更改通知适用于"查询返回的已更改数据"。 这意味着 - 如果您查询ID = 3的作业 - 只有对此记录的更改才会触发通知。

这里有很好的解释: SqlDependency OnChange Not Firing

事情是 - 在示例中,应用程序希望获得通知,如果"任何"表中的记录变了。 到目前为止这是有效的 - 并且(在答案中第1点上方的链接中)事件触发ONCE。

要重新触发此操作,您必须再次提交查询。 这就是样本的作用 - 它再次获取所有数据。

可能的解决方案(实现您的要求)是:

一个。通过调用来获取数据来触发请求 - 您不必在客户端上显示结果 - 只需执行查询。

B中。当事件触发时 - 再次进行查询 - (不将数据发送到客户端)

℃。你可以使用其他(额外)查询来查明发生了什么,或者只使用B的结果

D。)用signalR

发送信息

要获得更改,您必须找到一种比较数据的方法,因为SQL Server提供的唯一信息是"发生了一些事情" (以及什么) - 但不是哪些记录受到影响。

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlnotificationinfo(v=vs.110).aspx

样本的另一个问题(我只是猜测)是,如果你有多个客户端正在倾听 - 每个客户端将会重新触发"重新触发"再次 - 这可能(我不确定)在很多订阅事件中。

所以下次它会多次触发 - 导致多个请求......

所以要扩展上面的示例(除上述步骤外):

1。)更改GetData,如果已经订阅,则不会再次重新触发

2.。)提供额外的功能,通知客户有关更改 - 客户看到的一些""旗 - 更改清除此标志(触发器) - 通知清除它

3。)更改您可以轻松找到更改记录的数据库架构 - 在您将显示已删除的内容的情况下,一些额外的表格用于保存已删除的记录

另一种方法(不使用SQLChangeNotifications)是将CLR代码保存在数据库中。 此代码可以调用通知客户端的集线器。 但是这样的解决方案取决于几个因素。

a。)可以在SQL Server中运行signalR客户端

b。)您的策略是否允许数据库服务器与Web服务器通信

c。)您的策略是否允许SQL CLR集成

例如)....

第二种方法对我来说更容易,因为您可以从SQL CLR触发器触发发送。 这使您可以在没有"额外列的情况下发送更改的数据"和"删除的元素"表。