Зависимость SQL в C # - PullRequest
       33

Зависимость SQL в C #

4 голосов
/ 25 января 2012

Я пытаюсь выяснить, как использовать SQL-зависимость (C # 4.0) для «прослушивания» изменений в базе данных.Я видел довольно много вещей в сети, но они, кажется, приспособлены (естественно) для использования зависимости для извлечения тех же данных, от которых зависит зависимость SQL.Например, эта статья .

То, что я пытаюсь сделать, - это создать зависимость, которая при запуске приводит к ряду различных запросов SQL «Выбрать» (которые я могу сохранитьдругими способами и т. д.).Например: я пытаюсь установить зависимость, которая следит за количеством строк в таблице.Когда число строк увеличивается, тогда выполняйте x, y, z (то есть моей программе не важно, какое количество строк, только то, что оно увеличено, и когда оно делает кучу вещей).

Есть мысли о том, как лучше всего это сделать?

РЕДАКТИРОВАТЬ: я приложил свой код, как у меня сейчас.Я пытаюсь выяснить, как отделить настройку SqlDependency от процесса GetData ().Хотя в настоящее время, я думаю, что я вхожу в бесконечный цикл, поскольку после удаления обработчика события и повторного запуска «SetupSqlDependency ()», он возвращается обратно в обработчик события

    private void SetupSQLDependency()
    {
        // Tutorial for this found at:
        // http://www.dreamincode.net/forums/topic/156991-using-sqldependency-to-monitor-sql-database-changes/

        SqlDependency.Stop(connectionString);
        SqlDependency.Start(connectionString);

        sqlCmd.Notification = null;

        // create new dependency for SqlCommand
        SqlDependency sqlDep = new SqlDependency(sqlCmd);
        sqlDep.OnChange += new OnChangeEventHandler(sqlDep_OnChange);

        SqlDataReader reader = sqlCmd.ExecuteReader();
    }
 private void sqlDep_OnChange(object sender, SqlNotificationEventArgs e)
    {
        // FROM: http://msdn.microsoft.com/en-us/a52dhwx7.aspx

        #region
        // This event will occur on a thread pool thread.
        // Updating the UI from a worker thread is not permitted.
        // The following code checks to see if it is safe to
        // update the UI.

        /* ISynchronizeInvoke i = (ISynchronizeInvoke)this;

         // If InvokeRequired returns True, the code
         // is executing on a worker thread.
         if (i.InvokeRequired)
         {
             // Create a delegate to perform the thread switch.
             OnChangeEventHandler tempDelegate = new OnChangeEventHandler(sqlDep_OnChange);

             object[] args = { sender, e };

             // Marshal the data from the worker thread
             // to the UI thread.
             i.BeginInvoke(tempDelegate, args);

             return;
         }*/
        #endregion

        // Have to remove this as it only work's once
        SqlDependency sqlDep = sender as SqlDependency;
        sqlDep.OnChange -= sqlDep_OnChange;

        // At this point, the code is executing on the
        // UI thread, so it is safe to update the UI..

        // 1) Resetup Dependecy
        SetupSQLDependency();

    }

1 Ответ

5 голосов
/ 25 января 2012

Вы можете подключить событие SqlDependency.Change и делать все что угодно в этом обработчике событий.Фактически это единственный способ сделать то, что вы хотите, и в этом нет ничего плохого.

В псевдокоде это выглядит так:

var dep = new SqlDependency(GetSqlQueryForMonitoring());
dep.Change += () => {
 var data = ExecSql(GetDataQuerySql());
 UpdateCache(data);
};

Очень просто.Просто используйте два разных запроса.

Редактировать: в вашем примере кода есть комментарий о том, что вы работаете в потоке пользовательского интерфейса.Почему это так?Я сомневаюсь.В любом случае, вы должны выполнить свой запрос, прежде чем перезагружать зависимость, потому что в противном случае у вас будет возможность одновременных недействительных действий.

Я предлагаю вам получить свежие данные из базы данных, а затем отправить сообщение в пользовательский интерфейс для обновления.это (Invoke).

...