Как отслеживать изменения в DB MS SQL 2008 на C# через Service Broker?

173
07 августа 2018, 20:50

Никак не могу разобраться с вопросом отслеживания изменений в базе данных.

Имеется:

  • Приложение, написанное на C#
  • SQL Server, с базой данной на 3 таблички

В программе делаю следующее:

public Main_Form()
{
    InitializeComponent();
    SqlDependency.Stop(connectionString);
    SqlDependency.Start(connectionString);
    ScoutingSQL();
    DataGridView_Load();
}
//  создаем dependency и подписываем его на событие
// которое должно вызвать Service Broker 
private void ScoutingSQL()
{
    SqlConnection connection = new SqlConnection(connectionString);
    connection.Open();
    SqlCommand command = new SqlCommand("SELECT sentDate, verificationDate, verifiedTo", connection);
    SqlDependecy dependency = new SqlDependency(command);
    dependency.OnChange += new OnChangeEventHandler(OnDependencyChange);
}
// метод, вызванный событием
void OnDependencyChange(object sender, SqlNotificationEventArgs e)
{
    DataGridView_Load();
}
// Загружаем данные из sql бд в наш грид
public void DataGridView_Load()
{
    while(dataGridView1.Rows.Count > 0)
       for (int i = 0; i < dataGridView1.Rows[i]);
       {
           dataGridView1.Rows.Remove(dataGridView1.Rows[i]);
       }
    string tableName = "[staff_106].[dbo].[staff]"
    string querry = ("SELECT * FROM" + tableName + "");
    SqlConnection connection = new SqlConnection(connectionString);
    SqlDataAdapter dataAdapter = new SqlDataAdapter(querry, connection);
    // и тд... просто делаем  Fill из dataSet, заполняя грид.
}

Кусок для SqlDependency писал по этому примеру

В самой бд сделал ALTER DATABASE [Database_name] SET ENABLE_BROKER;

Но... по какой-то причине, по ПКМ->Свойства->Отслеживание изменений в поле Отслеживание изменений висело False. Ну, ручками переключил на True.

Запускаю приложение, меняю что-то в бд через SQL SMS и... ничего не происходит. Проверял брейкпоинтом, по событию даже не вызывается метод.

У меня появилось ряд вопросов, в ходе изучения матчасти.

1) Queue. Как узнать имя моей очереди по дефолту. Как её конфигурировать? Потому что, как я понял, у меня не совсем полный код для SqlDependency, т.к. требуется

SqlDependency.Start(connectionString, queueName); 

но queueName я не знаю.

2) Мне нужно только узнавать о том, были изменения или нет. Какие конкретно, мне не важно, и непонятно для чего в примере висит этот кусок:

// Execute the command.  
using (SqlDataReader reader = command.ExecuteReader())  
    {  
        // Process the DataReader.  
    }  

Точнее как, понятно, что по идее по правильному я должен подтянуть те самые изменения из Queue и уже дальше работать с ними, к примеру, ими заполнить ячейку в гриде, а не заполнять заново весь грид (но он у меня мелкий и особо я не теряю от Fill), но, вероятно, это что-то нужное, раз у меня не влзелето?

3) Как в SQL SMS проверить работает ли вообще Service Broker? Я читал про сообщения в бд, на которые должен, якобы, ответить Service Broker, но конкретного ничего не вычитал (что он должен ответить, в какой форме, куда, как смотреть этот пакет в таком случае).

Я понимаю, что вопросы крайне глупые, и надеюсь на ваше терпение. Благодарю за любую помощь и пояснения по моему вопросу.

Answer 1

Намучался в своё время с сервис-брокером, вот этот код работает (естественно на стороне БД всё тоже должно быть правильно настроено):

public class ServiceBrokerWatcher
{
    public ServiceBrokerWatcher(string conn, string query)
    {
        dependencyQuery = query;
        connectionString = conn;
        StartWatching(conn);
        ExecuteWatchingQuery();
    }
    private readonly string dependencyQuery;
    private readonly string connectionString;
    public event EventHandler ContextChangedEvent;
    private SqlDependency sqlDependency;
    public static void StartWatching(string connectionString)
    {
        SqlDependency.Stop(connectionString);
        SqlDependency.Start(connectionString);
    }
    private void ExecuteWatchingQuery()
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
            using (SqlCommand command = new SqlCommand(dependencyQuery, connection))
            {
                sqlDependency = new SqlDependency(command);
                sqlDependency.OnChange += OnDatabaseChange;
                command.Execute();
            }
        }
    }
    private void OnDatabaseChange(object sender, SqlNotificationEventArgs args)
    {
        try
        {
            if (sqlDependency != null)
            {
                sqlDependency.OnChange -= OnDatabaseChange;
            }
            ExecuteWatchingQuery();
            SqlNotificationInfo info = args.Info;
            if (SqlNotificationInfo.Insert.Equals(info)
                || SqlNotificationInfo.Update.Equals(info)
                || SqlNotificationInfo.Delete.Equals(info))
            {
                AppLogger.Logger.Debug("Обновление данных!");
                if (ContextChangedEvent != null)
                {
                    ContextChangedEvent(this, new EventArgs());
                }
            }
        }
        catch (Exception ex)
        {
            Logger.AppLogger.Logger.Error(ex.Message, ex.StackTrace);
        }
    }
}

Использовать примерно так:

    internal void ServiceBrokerWatcherInit()
    {
        updateWatcher = new ServiceBrokerWatcher(MainForm.DBConnectString, @"select id from dbo.ProductHistory");
        updateWatcher.ContextChangedEvent += updateWatcher_ContextChangedEvent;
    }
READ ALSO
WPF Как реализовать асинхронность

WPF Как реализовать асинхронность

Имеется команда, которая по выделенной книге находит студентов, которым выдана книга

172
Слежение за изменением Transform Unity

Слежение за изменением Transform Unity

Как можно отследить, кто изменяет значения Transform у какого - нибудь объекта на сцене? В интернете есть ответы, но там они в основном состоят...

183
Как сменить цвет таблицы в backpack for laravel?

Как сменить цвет таблицы в backpack for laravel?

Есть в админке таблица с отзывами

172