【问题标题】:SqlDependency Only Fires On SubscribeSqlDependency 仅在订阅时触发
【发布时间】:2015-12-03 20:08:24
【问题描述】:

我正在尝试在 SignalR 项目中使用 SqlDependancy,但我似乎无法让 OnChanged 事件多次触发。它最初在订阅事件上触发,但在对底层数据库进行更改后不再触发。我省略了 SignalR 和控制器代码,因为问题似乎出在存储库类中。 SqlDependancy.Start() 在我的 Global.asax 类中声明。

从 SQL 服务器观察,我可以看到在我的应用程序启动时创建了一个通知队列,并在我关闭时终止。

    public IEnumerable<Visitor> NotifyAllClients()
    {
        List<Visitor> visitors = new List<Visitor>();
        using (var connection = new SqlConnection(new VisitorLogEntities().Database.Connection.ConnectionString))
        {
            using (var command = new SqlCommand(@"SELECT * FROM dbo.Visitors", connection))
          //using (var command = new SqlCommand(@"SELECT [Id],[AgreeToTerms],[Base64Image],[CheckInDate],[CheckOutTime],[Company],[CountryOfOrigin],[email],[FirstName],[LastName],[IsInBuilding],[MeetingSubject],[MeetingTime],[PatriotHost],[phone],[title] FROM dbo.Visitors", connection))
            {

                var dependency = new SqlDependency(command);
                dependency.OnChange += Database_OnChange;

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

                var reader = command.ExecuteReader();

                while (reader.Read())
                {
                 ////compile visitor objects
                 ////visitors.add(new Visitor());
                }
            }
            return visitors.OrderByDescending(x => x.CheckInDate);
        }
    }

    private void Database_OnChange(object sender, SqlNotificationEventArgs e)
    {
        //var dependency = (SqlDependency)sender;
        //dependency.OnChange -= Database_OnChange;

        ////this fires once, with the Type of 'Subscribe', but then never fires on CRUD changes
        if (e.Type == SqlNotificationType.Change)
        {
            VisitorHub.SendVisitors();
        }
        //NotifyAllClients();
    }

编辑:上面注释掉的代码行表明需要进行更改才能使其正常工作。

【问题讨论】:

  • 我相信您需要在每次通知后重新订阅。 stackoverflow.com/questions/15566966/…
  • 我明白这一点,但如果我重新订阅它,它只会使用“订阅”类型再次触发 OnChanged 处理程序。代码的哪一部分是重新订阅?我假设它是 command.ExecuteReader() 方法,但是一旦触发订阅就结束了。重新订阅将在哪里进行?
  • 查看来自 msdn msdn.microsoft.com/en-US/library/a52dhwx7(v=vs.80).aspx 的示例,特别注意观察程序应用程序中的第 12 步和第 13 步。在第 12 步中,您将看到 onChange 事件被删除,然后它调用第 13 步再次设置它。
  • 所以基本上在单步调试时,它只是循环设置依赖关系,使用订阅事件点击 on changed 处理程序,然后将其拆除。一遍又一遍地。至少这是我看到的行为。
  • 我认为由于您的 sql 语句本身,您看到了不良行为。 sql语句必须遵循一些规则。有关更多信息,请参阅msdn.microsoft.com/en-US/library/aewzkxxh(v=vs.80).aspx。特别是编写通知查询部分。 “该语句不能使用星号 (*) 或 table_name.* 语法来指定列。”

标签: c# sql-server signalr sqldependency


【解决方案1】:

从 msdn http://msdn.microsoft.com/en-US/library/a52dhwx7(v=vs.80).aspx 查看此示例。下载 VS2005_General_en-us.pdf。第 24636 页,“在 Windows 应用程序中使用 SqlDependency”是原始链接指向的部分。请特别注意观察程序应用程序中的第 12 步和第 13 步。在第 12 步中,您将看到 onChange 事件的删除,然后它调用第 13 步再次设置它。

另外,我认为您看到的不良行为是由于您的 sql 语句本身造成的。 sql语句必须遵循一些规则。有关更多信息,请参阅https://technet.microsoft.com/en-us/library/ms181122(v=sql.105).aspx。特别是编写通知查询部分。 "该语句不能使用星号 (*) 或 table_name.* 语法来指定列。"

【讨论】:

  • 两个链接都坏了,你能更新一下吗?我也有同样的问题!
  • 我已经更新了答案。第一个链接指向您必须下载的文档才能查看我所指的内容。我将第二个链接更新为工作链接。
  • 我使用了星号(*),但删除它后,它现在看到 on Change 事件。谢谢
猜你喜欢
  • 1970-01-01
  • 2019-01-24
  • 1970-01-01
  • 1970-01-01
  • 2019-11-16
  • 2013-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多