SqlDependency 不适用于现有数据库
SqlDependency not working with Existing Database
我将 Signalr 与 SqlDependency 结合使用。我的代码有效,它向我显示了我想要的实时结果。但问题是它正在运行我新创建的数据库。如果我将数据库更改为旧数据库,SqlDependency 将停止工作并且不会在我的数据库 table 上进行更改检测。
下面是我的代码:
#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 网络服务,所以我总是更新我的网络服务的引用。另外,我在两个数据库上 enable_broker 都设置为 true。
数据库屏幕截图:
NotifyDB
eprocure
输出
请告诉我我的代码哪里做错了。提前致谢。
请确保启用了查询通知和服务代理,并授予了 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>”
让我们结束这个。在网上集思广益后,我成功地找到了答案。
我已经使用以下查询检查了我的数据库 sys.transmission_queue
:
select * from sys.transmission_queue
我们的通知很可能会在那里,因为它们无法送达而被保留。 transmission_status 解释了为什么会这样。
我发现有以下错误:
Error: 15517, State: 1. Cannot execute as the database principal because the principal "dbo" does not exist
Google 它并发现以下有用 link:
Troubleshooting SQL Server Error 15517
之后我 运行 下面的查询在上面 link
中有简要定义
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 依赖性工作正常。这都是我的结局。谢谢你帮我解决这个 post。感谢您抽出宝贵时间。快乐编码。
我将 Signalr 与 SqlDependency 结合使用。我的代码有效,它向我显示了我想要的实时结果。但问题是它正在运行我新创建的数据库。如果我将数据库更改为旧数据库,SqlDependency 将停止工作并且不会在我的数据库 table 上进行更改检测。
下面是我的代码:
#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 网络服务,所以我总是更新我的网络服务的引用。另外,我在两个数据库上 enable_broker 都设置为 true。
数据库屏幕截图:
NotifyDB
eprocure
输出
请告诉我我的代码哪里做错了。提前致谢。
请确保启用了查询通知和服务代理,并授予了 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>”
让我们结束这个。在网上集思广益后,我成功地找到了答案。
我已经使用以下查询检查了我的数据库 sys.transmission_queue
:
select * from sys.transmission_queue
我们的通知很可能会在那里,因为它们无法送达而被保留。 transmission_status 解释了为什么会这样。
我发现有以下错误:
Error: 15517, State: 1. Cannot execute as the database principal because the principal "dbo" does not exist
Google 它并发现以下有用 link:
Troubleshooting SQL Server Error 15517
之后我 运行 下面的查询在上面 link
中有简要定义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 依赖性工作正常。这都是我的结局。谢谢你帮我解决这个 post。感谢您抽出宝贵时间。快乐编码。