Проблемы с SqlDependency, Visual C ++ .Net 3.5, SQL Server 2008 - PullRequest
0 голосов
/ 09 февраля 2012

У меня возникли проблемы с интеграцией службы SqlDependency с моим приложением Windows Forms, и я надеялся, что кто-то может помочь новичку. Я просто хочу предвосхитить это, я знаю, что моя строка подключения к базе данных и мои операторы запросов верны. Кроме того, я знаю, что сервисный брокер включен в моей базе данных. Выпуск:

SELECT is_broker_enabled FROM sys.databases WHERE name = 'Database'

Возвращает 1 из запроса.

Я запускаю зависимость в моем событии загрузки основных форм, вот так:

SqlDependency::Stop(Get_DB_String());
SqlDependency::Start(Get_DB_String());

Затем я извлекаю из своей базы данных следующее:

    bindingSource->DataSource = GetData("Select * From Table", 
                                              Get_DB_String(), 
                                                 dataAdapter);
    dataGridView->DataSource = bindingSource;

Где GetData определяется как:

DataTable^ GetData( String^ sqlCommand, String^ connectionString, SqlDataAdapter^ adapter )
   {
      SqlConnection^ Connection = gcnew SqlConnection(connectionString);
      SqlCommand^ command = gcnew SqlCommand(sqlCommand,Connection);
      command->Notification = nullptr;              
      SqlDependency^ dependency = gcnew SqlDependency(command);     
      dependency->OnChange += gcnew OnChangeEventHandler(this, &LabSchedule::Form1::OnChange);
      adapter->SelectCommand = command;
      DataTable^ table = gcnew DataTable;
      adapter->Fill(table);  
      return table;
   }

И мой обработчик изменений определяется следующим образом:

System::Void OnChange(System::Object^ sender, SqlNotificationEventArgs^ e)
{

    ISynchronizeInvoke^ i = (ISynchronizeInvoke^)this;

    if (i->InvokeRequired)
    {

        OnChangeEventHandler^ tempDelegate =
            gcnew OnChangeEventHandler(this, &LabSchedule::Form1::OnChange);

        array<System::Object^>^ args = { sender, e };

        i->BeginInvoke(tempDelegate, args);

        return;
    }

    SqlDependency^ dependency = (SqlDependency^)sender;
    dependency->OnChange -= gcnew OnChangeEventHandler(this, &LabSchedule::Form1::OnChange);

    if(dependency->HasChanges)
    {
        // This is where I check the properties of the notification  
        MessageBox::Show(e->Info.ToString() + "\n" + e->Source.ToString() + "\n" + e->Type.ToString());
    }

}

Когда я изменяю что-то в своей базе данных с локального клиента, он запускает событие изменения, и все выглядит хорошо. Однако, когда я инициирую изменение клиента на другом компьютере, событие OnChange никогда не запускается. Я предполагаю, что делаю что-то дурацкое, но у меня нет понимания, чтобы понять это. Благодарю.

1 Ответ

0 голосов
/ 13 февраля 2012

После, казалось бы, бесконечного количества исследований, проблема, с которой я столкнулся, была связана с дизайном моей таблицы, а не с моим кодом.Вот три вещи, которые я предположительно изменил, чтобы исправить проблему:

Оператор не должен ссылаться на большие типы объектов: текст, текст и изображение.

Iиспользовал «ntext» в качестве типа данных одного из моих столбцов.

В операторе нельзя использовать звездочку (*) или имя_таблицы. * синтаксис для указания столбцов.

Изначально я использовал подстановочный знак для выбора данных из моей таблицы.

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

Я не использовал имена таблиц, состоящие из двух частей, в моих инструкциях SELECT, т. е. "Table_name" вместо "dbo.Table_name".

This oneбыло трудно привязать, и я надеюсь, что это поможет кому-то еще с подобными проблемами.Я неправильно указал в своем первоначальном описании своей проблемы, потому что мои запросы, хотя и были совершенно законными, были недействительными для SqlNotifications.

...