I’m having some issues integrating the SqlDependency service with my Windows Forms App, and I was hoping someone could help a rookie out. I just want to preface this with that, I know my database connection string and my query statements are correct. Additionally, I know that the service broker is enabled on my database. Issuing:
SELECT is_broker_enabled FROM sys.databases WHERE name = 'Database'
Returns a 1 from the query.
I start the dependency in my main forms loading event, like so:
SqlDependency::Stop(Get_DB_String());
SqlDependency::Start(Get_DB_String());
Then I pull from my database as follows:
bindingSource->DataSource = GetData("Select * From Table",
Get_DB_String(),
dataAdapter);
dataGridView->DataSource = bindingSource;
Where GetData is defined as:
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;
}
And my change handler is defined as follows:
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());
}
}
When I change something in my database from my local client, it fires the change event and all seems well. However, when I initiate a change from a client on another machine, the OnChange event never gets fired. I’m assuming I’m doing something wacky, but I don’t have the insight to figure it out. Thanks.
After seemingly an endless amount of research, the problem I was having was rooted in the design of my table and not my code. Here were the three things that I presumably changed to remedy the problem:
The statement must not reference the large object types: text, ntext, and image.
I was using “ntext” as the data type of one of my columns.
The statement may not use the asterisk (*) or table_name.* syntax to specify columns.
Initially, I was using the wildcard to select data from my table.
The projected columns in the SELECT statement must be explicitly stated, and table names must be qualified with two-part names.
I wasn’t using two-part table names in my SELECT statements, i.e., “Table_name” instead of “dbo.Table_name”.
This one was a hard one to peg down, and I hope this helps anyone else having similar issues. I misspoke in my initial description of my problem, because my queries, though perfectly legal, were invalid for SqlNotifications.