このトピックでは、SQL Server データベースからクエリ通知メッセージを受信するように SQL アダプターを構成する方法について説明します。 通知を示すには、"Status" 列を含むテーブル Employee を検討してください。 このテーブルに新しいレコードが挿入されると、Status 列の値は 0 に設定されます。 通知を受信するようにアダプターを構成するには、Status 列が "0" のすべてのレコードを取得する SQL ステートメントを使用して通知を登録します。 これを行うには、 NotificationStatement バインディング プロパティに SQL ステートメントを指定します。 アダプター クライアントは、通知を受信した後、SQL Server データベースで後続のタスクを実行するロジックを含めることができます。 この例では、わかりやすくするために、アダプター クライアントは、"0" として Status 列を持つテーブル内のすべてのレコードを一覧表示します。
注
ユーザー定義型の列を持つテーブルに対して操作を実行する場合は、アプリケーションの開発を開始する前に、 SQL アダプター トピックを使用して、ユーザー定義型のテーブルとビュー に対する操作を参照してください。
SQL アダプターのバインド プロパティを使用した通知の構成
次の表は、SQL Server からの通知の受信を構成するために使用する SQL アダプターのバインド プロパティをまとめたものです。 SQL Server データベースから通知を受信するには、.NET アプリケーションの実行中にこれらのバインド プロパティを指定する必要があります。
バインディングプロパティ | 説明 |
---|---|
InboundOperationType | 実行する受信操作を指定します。 通知メッセージを受信するには、これを [通知] に設定します。 |
NotificationStatement | クエリ通知の登録に使用する SQL ステートメント (SELECT または EXEC <ストアド プロシージャ>) を指定します。 アダプターは、指定された SQL ステートメントの結果セットが変更された場合にのみ、SQL Server から通知メッセージを取得します。 |
NotifyOnListenerStart | リスナーの起動時にアダプターがアダプター クライアントに通知を送信するかどうかを指定します。 |
これらのプロパティの詳細については、BizTalk Adapter for SQL Server アダプターのバインド プロパティに関する情報をご覧ください。 SQL アダプターを使用して SQL Server から通知を受信する方法の詳細については、詳細を参照してください。
WCF サービス モデルを使用した通知の構成
WCF サービス モデルを使用して通知を受信するには、次の手順を実行する必要があります。
アダプターによって公開されるメタデータから 、通知 操作用の WCF サービス コントラクト (インターフェイス) を生成します。 これを行うには、アダプター サービス参照の追加プラグインを使用できます。
Employee テーブルに対する Select 操作用の WCF クライアントを生成します。 これを行うには、アダプター サービス参照の追加プラグインを使用できます。
このインターフェイスから WCF サービスを実装します。
サービス ホスト (System.ServiceModel.ServiceHost) を使用して、この WCF サービスをホストします。
このトピックで使用する例について
このトピックの例では、Employee テーブルの通知を受け取ります。 テーブルを生成するスクリプトがサンプルと共に提供されます。 サンプルの詳細については、 SQL アダプターのサンプルを参照してください。 このトピックに基づく サンプル Notification_ServiceModelも、SQL アダプターのサンプルと共に提供されています。
WCF サービス コントラクトとクラス
アダプター サービス参照の追加プラグインを使用して、WCF サービス コントラクト (インターフェイス) と 通知 操作のサポート クラスを作成できます。 WCF サービス コントラクトの生成の詳細については、「 SQL Server 成果物の WCF クライアントまたは WCF サービス コントラクトを生成する」を参照してください。
WCF サービス コントラクト (インターフェイス)
次のコードは、 通知 操作用に生成された WCF サービス コントラクト (インターフェイス) を示しています。
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://schemas.microsoft.com/Sql/2008/05/", ConfigurationName="NotificationOperation")]
public interface NotificationOperation {
// CODEGEN: Generating message contract since the wrapper namespace (https://schemas.microsoft.com/Sql/2008/05/Notification/) of message
// Notification does not match the default value (https://schemas.microsoft.com/Sql/2008/05/)
[System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="Notification")]
void Notification(Notification request);
}
メッセージ コントラクト
通知操作のメッセージ コントラクトを次に示します。
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="Notification", WrapperNamespace="http://schemas.microsoft.com/Sql/2008/05/Notification/", IsWrapped=true)]
public partial class Notification {
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/Sql/2008/05/Notification/", Order=0)]
public string Info;
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/Sql/2008/05/Notification/", Order=1)]
public string Source;
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/Sql/2008/05/Notification/", Order=2)]
public string Type;
public Notification() {
}
public Notification(string Info, string Source, string Type) {
this.Info = Info;
this.Source = Source;
this.Type = Type;
}
}
WCF サービス クラス
アダプター サービス参照の追加プラグインは、サービス コントラクト (インターフェイス) から実装された WCF サービス クラスのスタブを持つファイルも生成します。 ファイルの名前はSqlAdapterBindingService.cs。 このクラスに 通知 操作を直接処理するロジックを挿入できます。 次のコードは、アダプター サービス参照プラグインの追加によって生成される WCF サービス クラスを示しています。
namespace SqlAdapterBindingNamespace {
public class SqlAdapterBindingService : NotificationOperation {
// CODEGEN: Generating message contract since the wrapper namespace (https://schemas.microsoft.com/Sql/2008/05/Notification/)
// of message Notification does not match the default value (https://schemas.microsoft.com/Sql/2008/05/)
public virtual void Notification(Notification request) {
throw new System.NotImplementedException("The method or operation is not implemented.");
}
}
}
WCF サービス モデルを使用したクエリ通知の受信
このセクションでは、SQL アダプターを使用してクエリ通知を受信する .NET アプリケーションを記述する方法について説明します。
クエリ通知を受信するには
アダプター サービス参照の追加プラグインを使用して、Employee テーブルに対する選択操作用の WCF クライアントを生成します。 このクライアントを使用して、通知メッセージを受信した後に選択操作を実行します。 プロジェクトに新しいクラス TableOperation.cs を追加し、次のコードスニペットを追加して Select 操作を実行します。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Notification_ServiceModel { public class TableOperation { public void TableOp() { /////////////////////////////////////////////////////////////////////// // CREATING THE CLIENT /////////////////////////////////////////////////////////////////////// TableOp_dbo_EmployeeClient client = new TableOp_dbo_EmployeeClient("SqlAdapterBinding_TableOp_dbo_Employee"); client.ClientCredentials.UserName.UserName = "<Enter user name here>"; client.ClientCredentials.UserName.Password = "<Enter password here>"; /////////////////////////////////////////////////////////////////////// // OPENING THE CLIENT /////////////////////////////////////////////////////////////////////// try { Console.WriteLine("Opening Client..."); client.Open(); } catch (Exception ex) { Console.WriteLine("Exception: " + ex.Message); throw; } /////////////////////////////////////////////////////////////////////// // SELECTING THE LAST INSERTED RECORD FROM THE TABLE /////////////////////////////////////////////////////////////////////// schemas.microsoft.com.Sql._2008._05.Types.Tables.dbo.Employee[] selectRecords; try { selectRecords = client.Select("*", "where Status=0"); } catch (Exception ex) { Console.WriteLine("Exception: " + ex.Message); throw; } Console.WriteLine("The details of the newly added employee are:"); Console.WriteLine("********************************************"); for (int i = 0; i < selectRecords.Length; i++) { Console.WriteLine("Employee Name : " + selectRecords[i].Name); Console.WriteLine("Employee Designation: " + selectRecords[i].Designation); Console.WriteLine("Employee Status : " + selectRecords[i].Status); Console.WriteLine(); } Console.WriteLine("********************************************");
Von Bedeutung
このコード スニペットは、Point UDT 列を含む Employee テーブルに対して操作を実行するため、アプリケーションの実行中に、プロジェクトの \bin\Debug フォルダーの下に UDT DLL を配置してください。
アダプター サービス参照の追加プラグインを使用して、 通知 操作の WCF サービス コントラクト (インターフェイス) とヘルパー クラスを生成します。
詳細については、「 SQL Server 成果物の WCF クライアントまたは WCF サービス コントラクトを生成する」を参照してください。 必要に応じて、サービス コントラクトとヘルパー クラスの生成中にバインディング プロパティを指定できます。 これにより、生成された構成ファイルに正しく設定されます。
手順 2 で生成されたインターフェイスとヘルパー クラスから WCF サービスを実装します。 このクラスの Notification メソッドは、 Notification 操作から受信したデータの処理でエラーが発生した場合に、例外をスローして操作を中止できます。それ以外の場合、メソッドは何も返しません。 WCF サービス クラスの属性を次に示す必要があります。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
Notification メソッド内では、アプリケーション ロジックを直接実装できます。 このクラスは、SqlAdapterBindingService.csにあります。 この例のこのコードは、 SqlAdapterBindingService クラスを サブクラス化します。 このコードでは、受信した通知メッセージがコンソールに書き込まれます。 さらに、Select 操作を実行するために、TableOperation クラス内の TableOp メソッドが呼び出されます。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class NotificationService : SqlAdapterBindingNamespace.SqlAdapterBindingService { public override void Notification(Notification request) { Console.WriteLine("\nNew Notification Received"); Console.WriteLine("*************************************************"); Console.WriteLine(request.Info); Console.WriteLine(request.Source); Console.WriteLine(request.Type); Console.WriteLine("*************************************************"); // Invoke th TableOp method in the TableOperation class TableOperation Ops = new TableOperation(); Ops.TableOp(); } }
SQL アダプターは接続 URI の一部として資格情報を受け入れないので、SQL Server データベースの資格情報を渡すには、次のクラスを実装する必要があります。 アプリケーションの後半では、このクラスをインスタンス化して SQL Server 資格情報を渡します。
class NotificationCredentials : 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 NotificationCredentials(); clone.UserName.UserName = this.UserName.UserName; clone.UserName.Password = this.UserName.Password; return clone; } }
SqlAdapterBinding を作成し、バインディング プロパティを指定してクエリ通知を受信するようにアダプターを構成します。 これは、コードで明示的に行うか、構成で宣言によって行うことができます。 少なくとも、 InboundOperationType および NotificationStatement バインディング プロパティを指定する必要があります。
SqlAdapterBinding binding = new SqlAdapterBinding(); binding.InboundOperationType = InboundOperation.Notification; binding.NotificationStatement = "SELECT Employee_ID, Name FROM dbo.Employee WHERE Status=0"; binding.NotifyOnListenerStart = true;
手順 4 で作成 した NotificationCredentials クラスをインスタンス化して、SQL Server データベースの資格情報を指定します。
NotificationCredentials credentials = new NotificationCredentials(); credentials.UserName.UserName = "<Enter user name here>"; credentials.UserName.Password = "<Enter password here>";
手順 3 で作成した WCF サービスのインスタンスを作成します。
// create service instance NotificationService service = new NotificationService();
WCF サービスとベース接続 URI を使用して 、System.ServiceModel.ServiceHost のインスタンスを作成します。 ここで資格情報も指定する必要があります。
// Enable service host Uri[] baseUri = new Uri[] { new Uri("mssql://mysqlserver//mydatabase") }; ServiceHost serviceHost = new ServiceHost(service, baseUri); serviceHost.Description.Behaviors.Add(credentials);
サービス ホストにサービス エンドポイントを追加します。 これを行うには:
手順 5 で作成したバインディングを使用します。
資格情報を含む接続 URI と、必要に応じて受信 ID を指定します。
コントラクトを "NotificationOperation" として指定します。
// Add service endpoint: be sure to specify NotificationOperation as the contract Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?"); serviceHost.AddServiceEndpoint("NotificationOperation", binding, ConnectionUri);
通知メッセージを受信するには、サービス ホストを開きます。
// Open the service host to begin receiving notifications serviceHost.Open();
通知の受信を停止するには、サービス ホストを閉じます。
serviceHost.Close();
例
次の例は、Employee テーブルの通知メッセージを受信する .NET アプリケーションを示しています。
注
次のコード スニペットは 、TableOperation.cs クラスをインスタンス化し、 TableOp メソッドを呼び出します。 クラスとメソッドについては、手順 1 で説明します。
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 Notification_ServiceModel
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class NotificationService : SqlAdapterBindingNamespace.SqlAdapterBindingService
{
public override void Notification(Notification request)
{
Console.WriteLine("\nNew Notification Received");
Console.WriteLine("*************************************************");
Console.WriteLine(request.Info);
Console.WriteLine(request.Source);
Console.WriteLine(request.Type);
Console.WriteLine("*************************************************");
TableOperation Ops = new TableOperation();
Ops.TableOp();
}
}
class NotificationCredentials : 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 NotificationCredentials();
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
{
SqlAdapterBinding binding = new SqlAdapterBinding();
binding.InboundOperationType = InboundOperation.Notification;
binding.NotificationStatement = "SELECT Employee_ID, Name FROM dbo.Employee WHERE Status=0";
binding.NotifyOnListenerStart = true;
// This URI is used to specify the address for the ServiceEndpoint
// It must contain the InboundId (if any) that was used to generate
// the WCF service callback interface
Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?");
// This URI is used to initialize the ServiceHost. It cannot contain
// a query_string (InboundID); otherwise,an exception is thrown when
// the ServiceHost is initialized.
Uri[] baseUri = new Uri[] { new Uri("mssql://mysqlserver//mydatabase") };
NotificationCredentials credentials = new NotificationCredentials();
credentials.UserName.UserName = "<Enter user name here>";
credentials.UserName.Password = "<Enter password here>";
Console.WriteLine("Opening service host...");
NotificationService service = new NotificationService();
serviceHost = new ServiceHost(service, baseUri);
serviceHost.Description.Behaviors.Add(credentials);
serviceHost.AddServiceEndpoint("NotificationOperation", binding, ConnectionUri);
serviceHost.Open();
Console.WriteLine("Service host opened...");
Console.WriteLine("Waiting for notification...");
Console.WriteLine("\nHit <RETURN> to stop receiving notification");
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 receiving notifications
if (serviceHost.State == CommunicationState.Opened)
serviceHost.Close();
else
serviceHost.Abort();
}
}
}
}