SqlDependency не работает с существующей базой данных - PullRequest
0 голосов
/ 26 декабря 2018

Я использую 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, я всегда обновляю ссылку на мой веб-сервис.Кроме того, для enable_broker установлено значение true для обеих баз данных.

Снимки экрана базы данных:

NotifyDB

enter image description here

eprocure

enter image description here

enter image description here

выход

enter image description here

Пожалуйста, дайте мне знать, что я делаю неправильно в моем коде.Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Пусть побежит это.После некоторого мозгового штурма в Интернете я успешно нашел свой ответ.

Я проверил свою базу данных sys.transmission_queue, используя следующий запрос:

select * from sys.transmission_queue

Поскольку, скорее всего, наши уведомления будут там, сохранены, потому что они не могутбыть доставленным.У элемента Transmission_status есть объяснение, почему это происходит.

Я обнаружил, что есть ошибка ниже:

Ошибка: 15517, Состояние: 1. Невозможно выполнить роль участника базы данных, поскольку участник"dbo" не существует

Google это и нашел следующую полезную ссылку:

Устранение неполадок SQL Server Ошибка 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 соответствует допустимому имени входа, ошибка не генерируется.Я обнаружил, что в некоторых БД на одном из моих серверов.Хотя это не вызывает проблемы сейчас, я постараюсь исправить несоответствие.

Исправление ошибки:

Самый простой способ исправить ошибку - это использовать ALTER AUTHORIZATION в базах данных, которыеиметь НУЛЕВОЙ логин для dbo.Это так просто, как:

ALTER AUTHORIZATION ON DATABASE::eprocure TO sa;

Итак, наконец.Я получил то, что хочу, и моя зависимость от SQL работает нормально.Это все с моей стороны.Спасибо, вы помогли мне в этом посте.Я ценю ваше драгоценное время.Удачного кодирования.

0 голосов
/ 26 декабря 2018

Пожалуйста, убедитесь, что Query Notification & Service Broker включены и предоставлены разрешения для идентификации IIS.

Шаги для включения: https://techbrij.com/database-change-notifications-asp-net-signalr-sqldependency

Чтобы проверить, включен ли компонент Service Broker, выполните следующую инструкцию

SELECT name, is_broker_enabled FROM sys.databases

Чтобы включить компонент Service Broker

ALTER DATABASE <<DatabaseName>> SET ENABLE_BROKER

Предоставить разрешение пользователю

GRANT SUBSCRIBE QUERY NOTIFICATIONS TO “<<USERIDENTITY>”
...