4

SQL Dependency (C# 4.0) を使用してデータベースへの変更を「リッスン」する方法を理解しようとしています。私はウェブ上でかなりの数を見てきましたが、依存関係を使用して SQL 依存関係が依存しているのと同じデータをプルするように (自然に) 調整されているようです。たとえば、この記事.

私がやろうとしているのは、トリガーされると、さまざまな SQL 'Select' クエリが生成される依存関係を作成することです (他のメソッドなどに保存できます)。例: テーブル内の行数を監視する依存関係を設定しようとしています。行数が増えたら、x、y、z を実行します (つまり、私のプログラムは、行数が何なのかは気にせず、単に増加しただけで、多くのことを行う場合)。

これを行う最善の方法について何か考えはありますか?

編集:現在持っているコードを添付しました。GetData() プロセスから SqlDependency の設定を分離する方法を見つけようとしています。ただし、現在、イベントハンドラーを削除して「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();

    }
4

1 に答える 1

7

SqlDependency.Change イベントをフックして、このイベント ハンドラーで好きなことを行うことができます。実際、これはあなたが望むことを行う唯一の方法であり、何も悪いことではありません。

擬似コードでは、次のようになります。

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

とてもシンプルです。2 つの異なるクエリを使用するだけです。

編集: サンプル コードには、UI スレッドで実行しているというコメントがあります。なぜそうでなければならないのですか?疑わしい。とにかく、依存関係をリセットする前にクエリを実行する必要があります。そうしないと、同時に無効化が発生する可能性があります。

データベースから新しいデータを取得し、UI にメッセージを送信して更新することをお勧めします (Invoke)。

于 2012-01-24T21:12:01.187 に答える