SqlDependency无法与现有数据库一起使用

时间:2018-12-26 02:45:49

标签: c# webforms signalr sqldependency

我将Signalr与SqlDependency一起使用。我的代码有效,并且向我显示了所需的实时结果。但是问题在于它正在使用我新创建的数据库。如果我将数据库更改为旧数据库,则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

enter image description here

eprocure

enter image description here

enter image description here

输出

enter image description here

请让我知道我在代码中做错了什么。预先感谢。

2 个答案:

答案 0 :(得分: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依赖关系正常运行。这都是我的目的。谢谢您的帮助。感谢您的宝贵时间。编码愉快。

答案 1 :(得分:0)

请确保已启用查询通知和服务代理,并且已授予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>”