SqlDependency 问题,Visual C++ .Net 3.5、SQL Server 2008

发布于 2025-01-03 17:32:29 字数 2315 浏览 1 评论 0原文

我在将 SqlDependency 服务与我的 Windows 窗体应用程序集成时遇到一些问题,我希望有人可以帮助新手解决这个问题。我只想以此作为序言,我知道我的数据库连接字符串和查询语句是正确的。此外,我知道我的数据库已启用服务代理。发出:

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 事件永远不会被触发。我假设我正在做一些古怪的事情,但我没有洞察力来弄清楚。谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦毁影碎の 2025-01-10 17:32:29

经过看似无穷无尽的研究后,我遇到的问题根源在于我的表的设计,而不是我的代码。为了解决该问题,我可能更改了以下三件事:

语句不得引用大对象类型:text、ntext 和 image。

我使用“ntext”作为其中一个对象的数据类型我的专栏。

该语句不能使用星号 (*) 或 table_name.* 语法来指定列。

最初,我使用通配符从表中选择数据。

必须明确声明 SELECT 语句中的投影列,并且表名称必须使用两部分名称进行限定。

我没有在 SELECT 语句中使用两部分表名称,即“Table_name ”而不是“dbo.Table_name”。

这是一个很难确定的问题,我希望这可以帮助其他遇到类似问题的人。我在对问题的最初描述中说错了,因为我的查询虽然完全合法,但对于 SqlNotifications 来说是无效的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文