Language

SqlDependency を使用した変更の検出

クエリ結果が最初に取得されたものと異なることを検出するには、コマンドを実行する前に SqlDependency オブジェクトを SqlCommand に関連付けてください。 結果が変更されたときに通知を受け取るには、OnChange イベントをサブスクライブします。 また、依存関係の HasChanges プロパティを確認して、結果が変更されたかどうかを確認することもできます。

セキュリティの考慮事項

基になるデータが変更されるときに通知を受信するには、Startを呼び出します。 依存関係インフラストラクチャは、リスナー用に SqlConnection を開きます。 データベース プリンシパルに、必要な Service Broker とクエリ通知のアクセス許可を付与します。 コード アクセス セキュリティは、最新の.NETではサポートされていません。 詳細については、「クエリ通知の有効化」を参照してください。

例

次の手順では、依存関係を宣言し、コマンドを実行し、結果セットが変更されたときに通知を受け取る方法について説明します。

  1. アプリケーションの初期化時に、 SqlDependency.Start を呼び出してクライアント リスナーを開始します。

  2. サーバーに接続して Transact-SQL (T-SQL) ステートメントを定義するための SqlConnection および SqlCommand オブジェクトを作成します。

  3. SqlDependency オブジェクトを作成または再利用し、SqlCommand オブジェクトに関連付けます。 依存関係により、 SqlNotificationRequest オブジェクトが作成され、必要に応じてコマンドに関連付けられます。 通知要求には、依存関係の内部識別子が含まれています。 コンストラクターはリスナーを開始しません。

  4. イベント ハンドラーを OnChange オブジェクトの SqlDependency イベントにサブスクライブします。

  5. Executeメソッドのいずれかを使用してコマンドを実行します。 このコマンドには通知要求が含まれているため、サーバーは指定されたキューへの通知用にそのクエリを登録します。

  6. アプリケーションの終了時に、同じ接続文字列とキュー名でSqlDependency.Stopを呼び出してください。

その後ユーザーが基になるデータを変更した場合、Microsoft SQL Server でその変更に対して保留中の通知があることが検出され、SqlConnection を呼び出して作成された、基になる SqlDependency.Start を介して処理され、クライアントに転送される通知が送信されます。 クライアント リスナーで、無効化メッセージが受信されます。 次にクライアント リスナーで、関連付けられている SqlDependency オブジェクトが検索され、OnChange イベントが起動されます。

次のコード フラグメントは、サンプル アプリケーションの設計パターンを示しています。 Microsoft.Data.SqlClient NuGet パッケージをインストールし、C# または Visual Basic でMicrosoft.Data.SqlClientをインポートします。

これらのフラグメントは、既存の Service Broker キューを使用します。 queueNameをキューの非修飾名に設定し、notificationOptionsをservice=<service-name>;local database=<database-name>に設定します。 通知をそのキューにルーティングするサービスを指定します。 同じ接続文字列とキュー名をStartおよびStopに渡します。 詳細については、「 クエリ通知を有効にする」を参照してください。

Sub Initialization()
    ' Create a dependency connection.
    SqlDependency.Start(connectionString, queueName)
End Sub

Sub SomeMethod()
    ' Assume connection is an open SqlConnection.
    ' Create a new SqlCommand object.
    Using command As New SqlCommand( _
      "SELECT ShipperID, CompanyName, Phone FROM dbo.Shippers", _
      connection)

        ' Create a dependency and associate it with the SqlCommand.
        Dim dependency As New SqlDependency(command, notificationOptions, 0)
        ' Maintain the reference in a class member.
        ' Subscribe to the SqlDependency event.
        AddHandler dependency.OnChange, AddressOf OnDependencyChange

        ' Execute the command.
        Using reader = command.ExecuteReader()
            ' Process the DataReader.
        End Using
    End Using
End Sub

' Handler method
Sub OnDependencyChange(ByVal sender As Object, _
    ByVal e As SqlNotificationEventArgs)
    ' Handle the event (for example, invalidate this cache entry).
End Sub

Sub Termination()
    ' Release the dependency
    SqlDependency.Stop(connectionString, queueName)
End Sub
void Initialization()
{
    // Create a dependency connection.
    SqlDependency.Start(connectionString, queueName);
}

void SomeMethod()
{
    // Assume connection is an open SqlConnection.

    // Create a new SqlCommand object.
    using (SqlCommand command=new SqlCommand(
        "SELECT ShipperID, CompanyName, Phone FROM dbo.Shippers",
        connection))
    {

        // Create a dependency and associate it with the SqlCommand.
        SqlDependency dependency=new SqlDependency(command, notificationOptions, 0);
        // Maintain the reference in a class member.

        // Subscribe to the SqlDependency event.
        dependency.OnChange+=new
           OnChangeEventHandler(OnDependencyChange);

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

// Handler method
void OnDependencyChange(object sender,
   SqlNotificationEventArgs e )
{
  // Handle the event (for example, invalidate this cache entry).
}

void Termination()
{
    // Release the dependency.
    SqlDependency.Stop(connectionString, queueName);
}

関連項目