通过Sql Server数据库更改通知winforms应用程序

时间:2015-06-16 15:37:42

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

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

ALTER DATABASE [TestNotification] SET ENABLE_BROKER

我希望在更改SqlDependency表时使用user类来通知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);
            }

        }



    }
}

所有代理服务都在运行:

enter image description here

我启动了应用程序,然后我点击了按钮,最后我去了 Sql Server管理工作室并插入了一个新行。问题是应用程序中的消息框未显示,因此SQL Server不会通知c#应用程序!!!

所以我需要知道:

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

1 个答案:

答案 0 :(得分:3)

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

  

必须明确声明SELECT语句中的预计列,并且必须使用两部分名称限定表名。请注意,这意味着语句中引用的所有表必须位于同一数据库中。

(有关完整列表,请参阅https://msdn.microsoft.com/library/ms181122.aspx

您必须明确使用两部分名称(例如dbo.user而非user)。

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