【问题标题】:Notify winforms application by Sql Server database changes通过 Sql Server 数据库更改通知 winforms 应用程序
【发布时间】:2015-09-01 12:59:38
【问题描述】:

我创建了一个 Sql 服务器数据库,我在其中添加了一个名为 user 的表。然后我执行了这个脚本

ALTER DATABASE [TestNotification] SET ENABLE_BROKER

user 表发生更改时,我想使用SqlDependency 类通知winforms 应用程序。

 namespace Watcher
{
    public partial class Form1 : Form
    {
        private int changeCount = 0; 
        private const string statusMessage = "{0} changes have occurred."; 
        private DataSet dataToWatch = null;
        private SqlConnection connection = null;
        private SqlCommand command = null;

        public Form1()
        {
            InitializeComponent();
            button1.Enabled = CanRequestNotifications();
            this.FormClosed += Form1_FormClosed;
        }

        void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            SqlDependency.Stop(GetConnectionString());
            if (connection != null)
            {
                connection.Close();
            }
        }

        private bool CanRequestNotifications()
        {
            // In order to use the callback feature of the
            // SqlDependency, the application must have
            // the SqlClientPermission permission.
            try
            {
                SqlClientPermission perm =
                    new SqlClientPermission(
                    PermissionState.Unrestricted);

                perm.Demand();

                return true;
            }
            catch
            {
                return false;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {

            changeCount = 0;
            label1.Text = String.Format(statusMessage, changeCount);
            //SqlDependency.Stop(GetConnectionString());
            SqlDependency.Start(GetConnectionString());

            if (connection == null)
            {
                connection = new SqlConnection(GetConnectionString());
            }

            if (command == null)
            {
                command = new SqlCommand(GetSQL(), connection);
            }
            if (dataToWatch == null)
            {
                dataToWatch = new DataSet();
            }

            GetData();

        }

        private string GetConnectionString()
        {
            return @"Data Source=BILOG-PRT-12\SQLEXPRESS; Initial Catalog=TestNotification;Integrated Security=True";
        }

        private string GetSQL()
        {
            return "Select   [id],[nom],[prenom],[age]  from   [dbo].[user]";
        }


        private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
        {

            MessageBox.Show("modification Occurred");
            ISynchronizeInvoke i = (ISynchronizeInvoke)this;
            if (i.InvokeRequired)
            {
                OnChangeEventHandler tempDelegate =new OnChangeEventHandler(dependency_OnChange);
                object[] args = { sender, e };
                i.BeginInvoke(tempDelegate, args);
                return;
            }

            SqlDependency dependency = (SqlDependency)sender;
            dependency.OnChange -= dependency_OnChange;
            ++changeCount;
            label1.Text = String.Format(statusMessage, changeCount);
             GetData();

        }
        private void GetData()
        {

            //dataToWatch.Clear();
            //command.Notification = null;
            SqlDependency dependency = new SqlDependency(command);
            if (connection.State != ConnectionState.Open) connection.Open();
            using (var dr = command.ExecuteReader())
            {
                dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
            }

        }



    }
}

所有代理服务都在运行:

我启动了应用程序,然后我点击了按钮,最后我进入了 Sql Server 管理工作室,然后我插入了一个新行。问题是应用程序中的消息框没有显示,所以SQL Server没有通知c#应用程序!!!

所以我需要知道:

  1. 为什么会这样?
  2. 我忘记了哪一步?
  3. 如何解决此问题?

【问题讨论】:

  • 为什么每次通知后都重启SqlDependencyOnChange 处理程序将为每个通知触发,而不仅仅是第一个。
  • 另外,在随机后台线程上执行MessageBox.Show 并不是一个好主意。您确定代理服务实际上正在运行吗?您的应用程序是否与 SQL 服务器在同一台机器上?
  • @Luaan 应用在同一台机器,但是如何验证broker服务是否在运行
  • 检查控制面板管理工具中的服务列表,与任何其他服务一样。
  • @Luaan 我有三个代理服务并且它正在运行(在图片中)!!!

标签: c# .net sql-server winforms sqldependency


【解决方案1】:

SqlDependency 有很多限制。引用一个相关问题:

SELECT 语句中的投影列必须明确声明,表名必须用两部分名称限定。注意,这意味着语句中引用的所有表必须在同一个数据库中。

(查看https://msdn.microsoft.com/library/ms181122.aspx查看完整列表)

您必须明确使用由两部分组成的名称(例如 dbo.user 而不仅仅是 user)。

另外,您需要执行命令。它不只是自动开始工作:) 添加一个简单的using (var dr = command.ExecuteReader()) {} 就足够了。

【讨论】:

  • 请查看我的编辑,即使我更改代码,我也会遇到同样的问题,同样的查询在 Sql Server 中工作正常
  • @LamloumiAfif 你必须在调用ExecuteReader之前绑定SqlDependency,当然:)
  • 看我的更新,你的意思是SqlDependency dependency = new SqlDependency(command);必须在dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);之前调用
猜你喜欢
  • 1970-01-01
  • 2019-07-02
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 2010-10-27
相关资源
最近更新 更多