通过 Sql 服务器数据库更改通知 winforms 应用程序
Notify winforms application by Sql Server database changes
我创建了一个 Sql 服务器数据库,我在其中添加了一个名为 user
的 table。然后我执行了这个脚本
ALTER DATABASE [TestNotification] SET ENABLE_BROKER
我想在 user
table 更改时使用 SqlDependency
class 通知 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 服务器管理工作室 我插入了一个新行。问题是应用程序中的消息框未显示,因此 SQL 服务器未通知 c# 应用程序!!!
所以我需要知道:
- 为什么会这样?
- 我忘了哪一步了?
- 我该如何解决这个问题?
SqlDependency
有很多限制。引用一个相关问题:
The projected columns in the SELECT statement must be explicitly stated, and table names must be qualified with two-part names.Notice that this means that all tables referenced in the statement must be in the same database.
(完整列表请参阅 https://msdn.microsoft.com/library/ms181122.aspx)
您必须明确使用由两部分组成的名称(例如 dbo.user
而不仅仅是 user
)。
还有,你需要执行命令。它不只是开始自动工作 :) 添加一个简单的 using (var dr = command.ExecuteReader()) {}
就足够了。
我创建了一个 Sql 服务器数据库,我在其中添加了一个名为 user
的 table。然后我执行了这个脚本
ALTER DATABASE [TestNotification] SET ENABLE_BROKER
我想在 user
table 更改时使用 SqlDependency
class 通知 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 服务器管理工作室 我插入了一个新行。问题是应用程序中的消息框未显示,因此 SQL 服务器未通知 c# 应用程序!!!
所以我需要知道:
- 为什么会这样?
- 我忘了哪一步了?
- 我该如何解决这个问题?
SqlDependency
有很多限制。引用一个相关问题:
The projected columns in the SELECT statement must be explicitly stated, and table names must be qualified with two-part names.Notice that this means that all tables referenced in the statement must be in the same database.
(完整列表请参阅 https://msdn.microsoft.com/library/ms181122.aspx)
您必须明确使用由两部分组成的名称(例如 dbo.user
而不仅仅是 user
)。
还有,你需要执行命令。它不只是开始自动工作 :) 添加一个简单的 using (var dr = command.ExecuteReader()) {}
就足够了。