次の方法で共有


WCF サービス モデルを使用して SQL Server から厳密に型指定されたポーリング ベースのデータ変更メッセージを受信する

SQL Server から厳密に型指定されたポーリング メッセージを受信するように SQL アダプターを構成できます。 データベースをポーリングするためにアダプターが実行するポーリング ステートメントを指定できます。 ポーリング ステートメントには、結果セットを返す SELECT ステートメントまたはストアド プロシージャを指定できます。 厳密に型指定された結果セットを受け取るシナリオでは、厳密に型指定されたポーリングを使用する必要があります。 アダプターが厳密に型指定されたポーリングをサポートする方法の詳細については、「 ポーリングを使用した受信呼び出しのサポート」を参照してください。

Von Bedeutung

1 つのアプリケーションで複数のポーリング操作を行う場合は、接続 URI の一部として InboundID 接続プロパティを指定して一意にする必要があります。 指定した受信 ID が操作名前空間に追加され、一意になります。

このトピックがポーリングを説明する方法

このトピックでは、SQL アダプターが厳密に型指定されたデータ変更メッセージの受信をサポートする方法を示すために、.NET アプリケーションを作成し、 TypedPolling 操作の WCF サービス コントラクトを生成します。 WCF サービス コントラクトの生成中に、次のコードを指定してください。

  • 接続 URI の一部として InboundID を指定する必要があります。

  • PollingStatement バインディング プロパティのポーリング ステートメントを指定する必要があります。

    さらに、プロキシ クラスの生成中に他のポーリング関連のバインディング プロパティを指定する場合は、 PolledDataAvailableStatement を次のように指定します。

SELECT COUNT(*) FROM Employee

PolledDataAvailableStatement は、正の値を含む最初のセルで結果セットを返す必要があります。 最初のセルに正の値が含まれていない場合、アダプターはポーリング ステートメントを実行しません。

ポーリング ステートメントの一部として、次の操作を実行します。

  1. Employee テーブルからすべての行を選択します。

  2. ストアド プロシージャ (MOVE_EMP_DATA) を実行して、すべてのレコードを Employee テーブルから EmployeeHistory テーブルに移動します。

  3. ストアド プロシージャ (ADD_EMP_DETAILS) を実行して、Employee テーブルに新しいレコードを追加します。 この手順では、従業員の名前、指定、給与をパラメーターとして受け取ります。

    これらの操作を実行するには、WCF サービス コントラクトとヘルパー クラスを生成する際に 、PollingStatement バインディング プロパティに次を指定する必要があります。

SELECT * FROM Employee;EXEC MOVE_EMP_DATA;EXEC ADD_EMP_DETAILS John, Tester, 100000

ポーリング ステートメントが実行されると、Employee テーブルのすべてのレコードが選択され、SQL Server からのメッセージが受信されます。 MOVE_EMP_DATA ストアド プロシージャがアダプターによって実行されると、すべてのレコードが EmployeeHistory テーブルに移動されます。 次に、ADD_EMP_DETAILS ストアド プロシージャが実行され、Employee テーブルに新しいレコードが追加されます。 次のポーリング実行では、1 つのレコードのみが返されます。 このサイクルは、サービス ホストを閉じるまで続行されます。

SQL アダプターのバインド プロパティを使用した型指定ポーリングの構成

次の表は、データ変更メッセージを受信するようにアダプターを構成するために使用する SQL アダプター バインド プロパティをまとめたものです。 PollingStatement バインド プロパティ以外は、.NET アプリケーションの実行中に、このセクションに記載されている他のすべてのバインド プロパティが必要です。 WCF サービス コントラクト TypedPolling 操作を生成する前に、PollingStatement バインディング プロパティを指定する必要があります。

バインディングプロパティ 説明
InboundOperationType ポーリングTypedPolling、または通知の受信操作を実行するかどうかを指定します。 既定値は ポーリングです。 厳密に型指定されたポーリング メッセージを受信するには、これを TypedPolling に設定します。
ポーリングデータの利用可能声明 ポーリングに使用できるデータがあるかどうかを判断するためにアダプターが実行する SQL ステートメントを指定します。 SQL ステートメントは、行と列で構成される結果セットを返す必要があります。 行が使用可能な場合にのみ、 PollingStatement バインディング プロパティに指定された SQL ステートメントが実行されます。
PollingIntervalInSeconds SQL アダプターが PolledDataAvailableStatement バインディング プロパティに指定されたステートメントを実行する間隔を秒単位で指定します。 既定値は 30 秒です。 ポーリング間隔は、連続するポーリング間の時間間隔を決定します。 指定した期間内にステートメントが実行された場合、アダプターはその間隔の残りの時間を待機します。
PollingStatement SQL Server データベース テーブルをポーリングする SQL ステートメントを指定します。 ポーリング ステートメントには、単純な SELECT ステートメントまたはストアド プロシージャを指定できます。 既定値は null です。 ポーリングを有効にするには、 PollingStatement の値を指定する必要があります。 ポーリング ステートメントは、 PolledDataAvailableStatement バインディング プロパティによって決定されるポーリングに使用できるデータがある場合にのみ実行されます。 任意の数の SQL ステートメントをセミコロンで区切って指定できます。 大事な:TypedPolling の場合は、メタデータを生成する前に、このバインド プロパティを指定する必要があります。
PollWhileDataFound ポーリング対象のテーブルでデータが使用可能な場合に、SQL アダプターがポーリング間隔を無視し、 PolledDataAvailableStatement バインディング プロパティに指定された SQL ステートメントを継続的に実行するかどうかを指定します。 テーブルに使用可能なデータがない場合、アダプターは指定されたポーリング間隔で SQL ステートメントを実行するように戻ります。 既定値は falseです。

これらのプロパティの詳細については、BizTalk Adapter for SQL Server アダプターのバインド プロパティに関する情報をご覧ください。 SQL アダプターを使用して SQL Server をポーリングする方法の詳細については、詳細を参照してください。

WCF サービス モデルで厳密に型指定されたポーリングを構成する

WCF サービス モデルを使用するときに ポーリング 操作を受信するには、次の操作を行う必要があります。

  1. アダプターによって公開されるメタデータから TypedPolling 操作の WCF サービス コントラクト (インターフェイス) を生成します。 これを行うには、アダプター サービス参照の追加 Visual Studio プラグインを使用できます。 この例の WCF サービス コントラクトを生成する際は、次のことを確認してください。

    • InboundID従業員として指定します。

    • PollingStatement バインディング プロパティのポーリング ステートメントを指定します。 この例では、ポーリング ステートメントを次のように指定します。

      SELECT * FROM Employee;EXEC MOVE_EMP_DATA;EXEC ADD_EMP_DETAILS John, Tester, 100000
      
  2. このインターフェイスから WCF サービスを実装します。

  3. サービス ホスト (System.ServiceModel.ServiceHost) を使用して、この WCF サービスをホストします。

このトピックで使用する例について

このトピックの例では、Employee テーブルを定期的に照会します。 この例では、MOVE_EMP_DATAストアド プロシージャとADD_EMP_DETAILS ストアド プロシージャも使用します。 これらの成果物を生成するスクリプトは、サンプルと共に提供されます。 サンプルの詳細については、 SQL アダプターのサンプルを参照してください。 このトピックに基づく サンプル TypedPolling_ServiceModelも、SQL アダプターのサンプルと共に提供されています。

WCF サービス コントラクトとクラス

アダプター サービス参照の追加プラグインを使用して、WCF サービス コントラクト (インターフェイス) と TypedPolling 操作のサポート クラスを作成できます。 WCF サービス コントラクトの生成の詳細については、「 SQL Server 成果物の WCF クライアントまたは WCF サービス コントラクトを生成する」を参照してください。

WCF サービス コントラクト (インターフェイス)

次のコードは、 TypedPolling 操作用に生成された WCF サービス コントラクト (インターフェイス) を示しています。

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://schemas.microsoft.com/Sql/2008/05/", ConfigurationName="TypedPolling_Employee")]
public interface TypedPolling_Employee {

    // CODEGEN: Generating message contract since the wrapper namespace (https://schemas.microsoft.com/Sql/2008/05/TypedPolling/Employee) of message TypedPolling
    // does not match the default value (https://schemas.microsoft.com/Sql/2008/05/)
    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="TypedPolling")]
    void TypedPolling(TypedPolling request);
}

メッセージ コントラクト

メッセージ コントラクト名前空間は、接続 URI の InboundID パラメーター (指定されている場合) によって変更されます。 この例では、受信 ID を Employee として指定しました。 要求メッセージは、厳密に型指定された結果セットを返します。

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="TypedPolling", WrapperNamespace="http://schemas.microsoft.com/Sql/2008/05/TypedPolling/Employee", IsWrapped=true)]
public partial class TypedPolling {

[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/Sql/2008/05/TypedPolling/Employee", Order=0)]
    public schemas.microsoft.com.Sql._2008._05.TypedPolling.Employee.TypedPollingResultSet0[] TypedPollingResultSet0;

[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/Sql/2008/05/TypedPolling/Employee", Order=1)]
    public schemas.microsoft.com.Sql._2008._05.TypedPolling.Employee.TypedPollingResultSet1[] TypedPollingResultSet1;

    public TypedPolling() {
    }

    public TypedPolling(schemas.microsoft.com.Sql._2008._05.TypedPolling.Employee.TypedPollingResultSet0[] TypedPollingResultSet0, schemas.microsoft.com.Sql._2008._05.TypedPolling.Employee.TypedPollingResultSet1[] TypedPollingResultSet1) {
        this.TypedPollingResultSet0 = TypedPollingResultSet0;
        this.TypedPollingResultSet1 = TypedPollingResultSet1;
    }
}

WCF サービス クラス

アダプター サービス参照の追加プラグインは、サービス コントラクト (インターフェイス) から実装された WCF サービス クラスのスタブを持つファイルも生成します。 ファイルの名前はSqlAdapterBindingService.cs。 TypedPolling 操作を処理するロジックをこのクラスに直接挿入できます。 次のコードは、アダプター サービス参照プラグインの追加によって生成される WCF サービス クラスを示しています。

namespace SqlAdapterBindingNamespace {

    public class SqlAdapterBindingService : TypedPolling_Employee {

        // CODEGEN: Generating message contract since the wrapper namespace (https://schemas.microsoft.com/Sql/2008/05/TypedPolling/Employee) of message TypedPolling
        // does not match the default value (https://schemas.microsoft.com/Sql/2008/05/)
        public virtual void TypedPolling(TypedPolling request) {
            throw new System.NotImplementedException("The method or operation is not implemented.");
        }
    }
}

ポーリング操作用に厳密に型指定された受信メッセージを受信する

このセクションでは、SQL アダプターを使用して厳密に型指定された受信ポーリング メッセージを受信する .NET アプリケーションを記述する方法について説明します。

  1. アダプター サービス参照の追加プラグインを使用して、 TypedPolling 操作の WCF サービス コントラクト (インターフェイス) とヘルパー クラスを生成します。 この例の WCF サービス コントラクトを生成する際は、必ず以下を指定してください。

    • InboundIDEmployee として指定する必要があります。

    • PollingStatement バインディング プロパティのポーリング ステートメントを指定する必要があります。 この例では、ポーリング ステートメントを次のように指定します。

      SELECT * FROM Employee;EXEC MOVE_EMP_DATA;EXEC ADD_EMP_DETAILS John, Tester, 100000
      

      詳細については、「 SQL Server 成果物の WCF クライアントまたは WCF サービス コントラクトを生成する」を参照してください。 必要に応じて、サービス コントラクトとヘルパー クラスの生成中にバインディング プロパティを指定できます。 これにより、生成された構成ファイルに正しく設定されます。

  2. 手順 1 で生成されたインターフェイスとヘルパー クラスから WCF サービスを実装します。 このクラスの TypedPolling メソッドは、TypedPolling 操作から受信したデータの処理でエラーが発生した場合に、ポーリング トランザクションを中止する例外をスローできます。それ以外の場合、メソッドは何も返しません。 WCF サービス クラスの属性を次に示す必要があります。

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    

    TypedPolling メソッド内では、アプリケーション ロジックを直接実装できます。 このクラスは、SqlAdapterBindingService.csにあります。 この例のこのコードは、 SqlAdapterBindingService クラスを サブクラス化します。 このコードでは、厳密に型指定された結果セットとして受信したポーリング メッセージがコンソールに書き込まれます。

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    
    public class PollingService : SqlAdapterBindingNamespace.SqlAdapterBindingService
    {
        public override void TypedPolling(TypedPolling request)
        {
            Console.WriteLine("\nNew Polling Records Received");
            Console.WriteLine("*************************************************");
            Console.WriteLine("Employee ID\tName\tDesignation\tSalary");
    
            for (int i = 0; i < request.TypedPollingResultSet0.Length; i++)
            {
                Console.WriteLine("{0}\t{1}\t{2}\t{3}",
                request.TypedPollingResultSet0[i].Employee_ID,
                request.TypedPollingResultSet0[i].Name,
                request.TypedPollingResultSet0[i].Designation,
                request.TypedPollingResultSet0[i].Salary);
            }
            Console.WriteLine("*************************************************");
            Console.WriteLine("\nHit <RETURN> to stop polling");
        }
    }
    
  3. SQL アダプターは接続 URI の一部として資格情報を受け入れないので、SQL Server データベースの資格情報を渡すには、次のクラスを実装する必要があります。 アプリケーションの後半では、このクラスをインスタンス化して SQL Server 資格情報を渡します。

    class PollingCredentials : ClientCredentials, IServiceBehavior
    {
        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {
            bindingParameters.Add(this);
        }
    
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        { }
    
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        { }
    
        protected override ClientCredentials CloneCore()
        {
            ClientCredentials clone = new PollingCredentials();
            clone.UserName.UserName = this.UserName.UserName;
            clone.UserName.Password = this.UserName.Password;
            return clone;
        }
    }
    
  4. SqlAdapterBinding を作成し、バインド プロパティを指定してポーリング操作を構成します。 これは、コードで明示的に行うか、構成で宣言によって行うことができます。 少なくとも、 InboundOperationTypePolledDataAvailableStatementPollingStatement を指定する必要があります。

    SqlAdapterBinding binding = new SqlAdapterBinding();
    binding.InboundOperationType = InboundOperation.TypedPolling;
    binding.PolledDataAvailableStatement = "SELECT COUNT (*) FROM EMPLOYEE";
    binding.PollingStatement = "SELECT * FROM Employee;EXEC MOVE_EMP_DATA;EXEC ADD_EMP_DETAILS John, Tester, 100000";
    
  5. 手順 3 で作成 した PollingCredentials クラスをインスタンス化して、SQL Server データベースの資格情報を指定します。

    PollingCredentials credentials = new PollingCredentials();
    credentials.UserName.UserName = "<Enter user name here>";
    credentials.UserName.Password = "<Enter password here>";
    
  6. 手順 2 で作成した WCF サービスのインスタンスを作成します。

    // create service instance
    PollingService service = new PollingService();
    
  7. WCF サービスとベース接続 URI を使用して 、System.ServiceModel.ServiceHost のインスタンスを作成します。 基本接続 URI に受信 ID を含めることはできません。 ここで資格情報も指定する必要があります。

    // Enable service host
    Uri[] baseUri = new Uri[] { new Uri("mssql://mysqlserver//mydatabase") };
    ServiceHost serviceHost = new ServiceHost(service, baseUri);
    serviceHost.Description.Behaviors.Add(credentials);
    
    
  8. サービス ホストにサービス エンドポイントを追加します。 これを行うには:

    • 手順 4 で作成したバインディングを使用します。

    • 資格情報を含む接続 URI と、必要に応じて受信 ID を指定します。

    • コントラクトを "TypedPolling_Employee" として指定します。

    // Add service endpoint: be sure to specify TypedPolling_Employee as the contract
    Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?InboundID=Employee");
    serviceHost.AddServiceEndpoint("TypedPolling_Employee", binding, ConnectionUri);
    
  9. ポーリング データを受信するには、サービス ホストを開きます。 アダプターは、クエリが結果セットを返すたびにデータを返します。

    // Open the service host to begin polling
    serviceHost.Open();
    
  10. ポーリングを終了するには、サービス ホストを閉じます。

    Von Bedeutung

    アダプターは、サービス ホストが閉じられるまでポーリングを続行します。

    serviceHost.Close();
    

次の例は、Employee テーブルを実行するポーリング クエリを示しています。 ポーリング ステートメントは、次のタスクを実行します。

  1. Employee テーブルからすべてのレコードを選択します。

  2. MOVE_EMP_DATA ストアド プロシージャを実行して、すべてのレコードを Employee テーブルから EmployeeHistory テーブルに移動します。

  3. ADD_EMP_DETAILS ストアド プロシージャを実行して、1 つのレコードを Employee テーブルに追加します。

    最初のポーリング メッセージには、Employee テーブルのすべてのレコードが含まれます。 後続のポーリング メッセージには、ADD_EMP_DETAILS ストアド プロシージャによって挿入された最後のレコードのみが含まれます。 アダプターは、 <RETURN>を押してサービス ホストを閉じるまでポーリングを続行します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Adapters.Sql;
using Microsoft.ServiceModel.Channels;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Collections.ObjectModel;

namespace TypedPolling_ServiceModel
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

    public class PollingService : SqlAdapterBindingNamespace.SqlAdapterBindingService
    {
        public override void TypedPolling(TypedPolling request)
        {
            Console.WriteLine("\nNew Polling Records Received");
            Console.WriteLine("*************************************************");
            Console.WriteLine("Employee ID\tName\tDesignation\tSalary");

            for (int i = 0; i < request.TypedPollingResultSet0.Length; i++)
            {
                Console.WriteLine("{0}\t{1}\t{2}\t{3}",
                request.TypedPollingResultSet0[i].Employee_ID,
                request.TypedPollingResultSet0[i].Name,
                request.TypedPollingResultSet0[i].Designation,
                request.TypedPollingResultSet0[i].Salary);
            }
            Console.WriteLine("*************************************************");
            Console.WriteLine("\nHit <RETURN> to stop polling");
        }
    }

    class PollingCredentials : ClientCredentials, IServiceBehavior
    {
        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {
            bindingParameters.Add(this);
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        { }

        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        { }

        protected override ClientCredentials CloneCore()
        {
            ClientCredentials clone = new PollingCredentials();
            clone.UserName.UserName = this.UserName.UserName;
            clone.UserName.Password = this.UserName.Password;
            return clone;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost serviceHost = null;
            try
            {
                Console.WriteLine("Sample started...");
                Console.WriteLine("Press any key to start polling...");
                Console.ReadLine();

                SqlAdapterBinding binding = new SqlAdapterBinding();
                binding.InboundOperationType = InboundOperation.TypedPolling;
                binding.PolledDataAvailableStatement = "SELECT COUNT (*) FROM EMPLOYEE";
                binding.PollingStatement = "SELECT * FROM Employee;EXEC MOVE_EMP_DATA;EXEC ADD_EMP_DETAILS John, Tester, 100000";
                Console.WriteLine("Binding properties assigned...");

                // This URI is used to specify the address for the ServiceEndpoint
                // It must contain the InboundId that was used to generate
                // the WCF service callback interface
                Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?InboundId=Employee");

                // This URI is used to initialize the ServiceHost. It cannot contain
                // the InboundID; otherwise,an exception is thrown when
                // the ServiceHost is initialized.
                Uri[] baseUri = new Uri[] { new Uri("mssql://mysqlserver//mydatabase") };

                PollingCredentials credentials = new PollingCredentials();
                credentials.UserName.UserName = "<Enter user name here>";
                credentials.UserName.Password = "<Enter password here>";

                Console.WriteLine("Opening service host...");
                PollingService service = new PollingService();
                serviceHost = new ServiceHost(service, baseUri);
                serviceHost.Description.Behaviors.Add(credentials);
                serviceHost.AddServiceEndpoint("TypedPolling_Employee", binding, ConnectionUri);
                serviceHost.Open();
                Console.WriteLine("Service host opened...");
                Console.WriteLine("Polling started...");
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception :" + e.Message);
                Console.ReadLine();

                /* If there is an error it will be specified in the inner exception */
                if (e.InnerException != null)
                {
                    Console.WriteLine("InnerException: " + e.InnerException.Message);
                    Console.ReadLine();
                }
            }
            finally
            {
                // IMPORTANT: you must close the ServiceHost to stop polling
                if (serviceHost.State == CommunicationState.Opened)
                    serviceHost.Close();
                else
                    serviceHost.Abort();
            }
        }
    }
}

こちらもご覧ください

WCF サービス モデルで SQL アダプターを使用して SQL Server をポーリングする