【问题标题】:SqlDependency not working with Existing DatabaseSqlDependency 不适用于现有数据库
【发布时间】:2018-12-26 02:45:48
【问题描述】:

我正在使用带有 SqlDependency 的 Signalr。我的代码有效,它向我显示了我想要的实时结果。但问题是它正在使用我新创建的数据库。如果我将数据库更改为旧数据库,SqlDependency 将停止工作,并且无法在我的数据库表上进行更改检测。

下面是我的代码:

#region SignalRMethods
    [System.Web.Script.Services.ScriptMethod()]
    [System.Web.Services.WebMethod(EnableSession = true)]
    public GlobalApplicationError[] GetErrorsList()
    {
        var cs = "Data Source=.;Initial Catalog=NotifyDB;Integrated Security=True";
        using (var connection = new SqlConnection(cs))
        {
            connection.Open();
            SqlDependency.Start(cs);
            using (SqlCommand command = new SqlCommand(@"SELECT  [Form_Name],[Message],[Prepared_By_Date] FROM [GlobalApplicationError]", connection))
            {
                // Make sure the command object does not already have
                // a notification object associated with it.

                SqlDependency dependency = new SqlDependency(command);
                dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);

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

                using (var reader = command.ExecuteReader())
                    return reader.Cast<IDataRecord>()
                        .Select(x => new GlobalApplicationError()
                        {
                            Form_Name = x["Form_Name"].ToString(),
                            Message = x["Message"].ToString(),
                            Prepared_By_Date = Convert.ToDateTime(x["Prepared_By_Date"])
                        }).ToList().ToArray();
            }
        }
    }

    private static void dependency_OnChange(object sender, SqlNotificationEventArgs e)
    {
        MyHub.Show();
    }
    #endregion

如果我更改连接字符串中的数据库,上面的代码完全适用于数据库NotifyDB,但不适用于我现有的eprocure。由于我使用的是 asmx Web 服务,所以我总是更新我的 Web 服务的引用。另外,我在两个数据库上都将 enable_broker 设置为 true。

数据库截图:

NotifyDB

eprocure

输出

请让我知道我在代码中做错了什么。提前致谢。

【问题讨论】:

    标签: c# webforms signalr sqldependency


    【解决方案1】:

    让我们结束这个。在互联网上进行了一些头脑风暴后,我成功地找到了答案。

    我已经使用以下查询检查了我的数据库sys.transmission_queue

    select * from sys.transmission_queue

    我们的通知很可能会在那里,因为无法传递而被保留。 transmission_status 解释了为什么会发生这种情况。

    我发现有以下错误:

    错误:15517,状态:1。无法作为数据库主体执行,因为主体“dbo”不存在

    谷歌一下,发现以下有用的链接:

    Troubleshooting SQL Server Error 15517

    之后我运行上面链接中简要定义的以下查询

    EXEC sp_MSForEachDB 
    'SELECT ''?'' AS ''DBName'', sp.name AS ''dbo_login'', o.name AS ''sysdb_login''
    FROM ?.sys.database_principals dp
    LEFT JOIN master.sys.server_principals sp
    ON dp.sid = sp.sid
    LEFT JOIN master.sys.databases d 
    ON DB_ID(''?'') = d.database_id
    LEFT JOIN master.sys.server_principals o 
    ON d.owner_sid = o.sid
    WHERE dp.name = ''dbo'';';
    

    通过这样做,我发现了几个 sys.databases 说有所有者的数据库。但是,当我从数据库的 sys.database_principals 检查它时,SID 与 dbo 不匹配。我的 dbo_login 列返回 NULL。这是问题的一个明显迹象。您还可能会看到 dbo_login 和 sysdb_login 之间不匹配。看来只要 dbo_login 匹配合法登录,就不会生成错误。我在我的一台服务器上的一些数据库上发现了这一点。虽然它现在没有造成问题,但我会寻求纠正不匹配的问题。

    纠正错误:

    纠正错误的最简单方法是对 dbo 具有 NULL 登录匹配的数据库使用 ALTER AUTHORIZATION。很简单:

    ALTER AUTHORIZATION ON DATABASE::eprocure TO sa;

    最后。我得到了我想要的,我的 SQL 依赖运行正常。这都是我的目的。谢谢你在这篇文章上帮助我。感谢您宝贵的时间。快乐编码。

    【讨论】:

      【解决方案2】:

      请确保已启用查询通知和服务代理并授予 IIS 标识的权限。

      启用步骤:https://techbrij.com/database-change-notifications-asp-net-signalr-sqldependency

      要检查服务代理是否启用,请执行以下语句

      SELECT name, is_broker_enabled FROM sys.databases
      

      启用服务代理

      ALTER DATABASE <<DatabaseName>> SET ENABLE_BROKER
      

      向用户授予权限

      GRANT SUBSCRIBE QUERY NOTIFICATIONS TO “<<USERIDENTITY>”
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-26
        • 1970-01-01
        • 2017-10-01
        • 1970-01-01
        • 2018-12-19
        • 1970-01-01
        相关资源
        最近更新 更多