Уведомить приложение winforms об изменениях в базе данных Sql Server
Я создал базу данных сервера Sql, в которую я добавил таблицу с именем user
, Затем я выполнил этот скрипт
ALTER DATABASE [TestNotification] SET ENABLE_BROKER
Я хотел бы использовать SqlDependency
класс, чтобы уведомить приложение Winforms, когда user
стол был изменен.
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, и я вставил новую строку. Проблема в том, что окно сообщения в приложении не отображается, поэтому приложение C# не уведомляется SQL Server!!!
Так что мне нужно знать:
- Почему это происходит?
- Какой шаг я забыл?
- Как я могу решить эту проблему?
1 ответ
Там довольно много ограничений с SqlDependency
, Чтобы процитировать один соответствующий вопрос:
Проецируемые столбцы в операторе SELECT должны быть указаны явно, а имена таблиц должны быть дополнены именами из двух частей. Следует отметить, что это означает, что все таблицы, на которые есть ссылки в операторе, должны находиться в одной базе данных.
(полный список см. https://msdn.microsoft.com/library/ms181122.aspx).
Вы должны явно использовать имя из двух частей (например, dbo.user
вместо просто user
).
Также вам необходимо выполнить команду. Это не просто начинает работать автоматически:) Добавление простого using (var dr = command.ExecuteReader()) {}
должно быть достаточно.