SqlDependency を使用した変更の検出Detecting Changes with SqlDependency

クエリ結果が最初に取得されたクエリ結果と異なることを検出するために、SqlDependency オブジェクトを SqlCommand に関連付けることができます。A SqlDependency object can be associated with a SqlCommand in order to detect when query results differ from those originally retrieved. さらに、OnChange イベントにデリゲートを割り当てることができます。このイベントは、関連付けられたコマンドの結果が変わったときに発生します。You can also assign a delegate to the OnChange event, which will fire when the results change for an associated command. コマンドを実行する前に、コマンドを SqlDependency に関連付ける必要があります。You must associate the SqlDependency with the command before you execute the command. また、HasChangesSqlDependency プロパティを使用しても、データが最初に取得されて以降にクエリ結果が変化したかどうかを判別できます。The HasChanges property of the SqlDependency can also be used to determine if the query results have changed since the data was first retrieved.

セキュリティの考慮事項Security Considerations

指定されたコマンドについて基になるデータが変更されたという通知を受け取るために、依存関係を持つインフラストラクチャでは SqlConnection が呼び出されると、Start が開かれることを利用します。The dependency infrastructure relies on a SqlConnection that is opened when Start is called in order to receive notifications that the underlying data has changed for a given command. クライアントが SqlDependency.Start の呼び出しを開始できるかどうかは、SqlClientPermission を使用し、コード アクセス セキュリティ属性を利用することで制御します。The ability for a client to initiate the call to SqlDependency.Start is controlled through the use of SqlClientPermission and code access security attributes. 詳細については、「クエリ通知の有効化」および「コードアクセスセキュリティと ADO.NET」を参照してください。For more information, see Enabling Query Notifications and Code Access Security and ADO.NET.

Example

次の手順に従って、依存関係を宣言し、コマンドを実行して、結果セットが変更された場合に通知を受け取ります。The following steps illustrate how to declare a dependency, execute a command, and receive a notification when the result set changes:

  1. サーバーへの SqlDependency 接続を開始します。Initiate a SqlDependency connection to the server.

  2. SqlConnection および SqlCommand オブジェクトを作成し、サーバーに接続して、Transact-SQL ステートメントを定義します。Create SqlConnection and SqlCommand objects to connect to the server and define a Transact-SQL statement.

  3. SqlDependency オブジェクトを新しく作成するか、既存のものを使用して、それを SqlCommand オブジェクトにバインドします。Create a new SqlDependency object, or use an existing one, and bind it to the SqlCommand object. 内部的には、これによって SqlNotificationRequest オブジェクトが作成され、必要に応じてコマンド オブジェクトにバインドされます。Internally, this creates a SqlNotificationRequest object and binds it to the command object as needed. この通知要求には、この SqlDependency オブジェクトを一意に識別する内部 ID が含まれます。This notification request contains an internal identifier that uniquely identifies this SqlDependency object. クライアント リスナーがまだアクティブでない場合、それも起動されます。It also starts the client listener if it is not already active.

  4. OnChange オブジェクトの SqlDependency イベントにイベント ハンドラーを定期受信します。Subscribe an event handler to the OnChange event of the SqlDependency object.

  5. Execute オブジェクトの任意の SqlCommand メソッドを使用して、コマンドを実行します。Execute the command using any of the Execute methods of the SqlCommand object. このコマンドは通知オブジェクトにバインドされているため、サーバーは通知を生成する必要があることを認識し、キュー情報が依存関係を持つキューにポイントされます。Because the command is bound to the notification object, the server recognizes that it must generate a notification, and the queue information will point to the dependencies queue.

  6. サーバーへの SqlDependency 接続を停止します。Stop the SqlDependency connection to the server.

その後、基になるデータをユーザーが変更すると、Microsoft SQL Server ではその変更に対する保留通知を検出し、通知を送信します。その通知は、SqlConnection を呼び出すことで作成された基になる SqlDependency.Start を利用して処理され、クライアントに転送されます。If any user subsequently changes the underlying data, Microsoft SQL Server detects that there is a notification pending for such a change, and posts a notification that is processed and forwarded to the client through the underlying SqlConnection that was created by calling SqlDependency.Start. クライアント リスナーは無効なメッセージを受け取ります。The client listener receives the invalidation message. クライアント リスナーでは、関連付けられている SqlDependency オブジェクトを特定し、OnChange イベントを発生させます。The client listener then locates the associated SqlDependency object and fires the OnChange event.

次のコード フラグメントに、サンプル アプリケーションの作成に利用されるデザイン パターンを示します。The following code fragment shows the design pattern you would use to create a sample application.

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)
        ' Maintain the refernce 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);
        // 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);
}

関連項目See also