Freigeben über


Empfangen von Abfragebenachrichtigungen von SQL mithilfe des WCF-Dienstmodells

In diesem Thema wird veranschaulicht, wie Sie den SQL-Adapter so konfigurieren, dass er Abfragebenachrichtigungsmeldungen aus einer SQL Server Datenbank empfängt. Um Benachrichtigungen zu veranschaulichen, ziehen Sie eine Tabelle mit der Spalte "Status" in Betracht. Wenn ein neuer Datensatz in diese Tabelle eingefügt wird, wird der Wert der Spalte Status auf 0 festgelegt. Sie können den Adapter für den Empfang von Benachrichtigungen konfigurieren, indem Sie eine SQL-Anweisung verwenden, die alle Datensätze mit der Statusspalte "0" abruft. Dazu geben Sie die SQL-Anweisung für die NotificationStatement-Bindungseigenschaft an. Nachdem der Adapterclient die Benachrichtigung empfangen hat, kann er die Logik enthalten, um alle nachfolgenden Aufgaben für die SQL Server-Datenbank auszuführen. In diesem Beispiel listet der Adapterclient der Einfachheit halber alle Datensätze in der Tabelle auf, die die Statusspalte als "0" aufweisen.

Hinweis

Wenn Sie Vorgänge für Tabellen ausführen, die Spalten mit benutzerdefinierten Typen enthalten, sollten Sie unter Vorgänge für Tabellen und Ansichten mit benutzerdefinierten Typen das SQL-Adapterthema verwenden , bevor Sie mit der Entwicklung Ihrer Anwendung beginnen.

Konfigurieren von Benachrichtigungen mit den SQL-Adapterbindungseigenschaften

In der folgenden Tabelle sind die SQL-Adapterbindungseigenschaften zusammengefasst, die Sie zum Konfigurieren des Empfangens von Benachrichtigungen von SQL Server verwenden. Sie müssen diese Bindungseigenschaften beim Ausführen der .NET-Anwendung angeben, um die Benachrichtigungen von einer SQL Server-Datenbank zu empfangen.

Bindungseigenschaft BESCHREIBUNG
InboundOperationType Gibt den eingehenden Vorgang an, den Sie ausführen möchten. Legen Sie zum Empfangen von Benachrichtigungen dies auf Benachrichtigung fest.
NotificationStatement Gibt die SQL-Anweisung (gespeicherte SELECT- oder EXEC-Prozedur><) an, die zum Registrieren von Abfragebenachrichtigungen verwendet wird. Der Adapter ruft nur dann eine Benachrichtigung von SQL Server ab, wenn sich das Resultset für die angegebene SQL-Anweisung ändert.
NotifyOnListenerStart Gibt an, ob der Adapter beim Starten des Listeners eine Benachrichtigung an die Adapterclients sendet.

Eine ausführlichere Beschreibung dieser Eigenschaften finden Sie unter Informationen zum BizTalk-Adapter für SQL Server Adapterbindungseigenschaften. Eine vollständige Beschreibung der Verwendung des SQL-Adapters zum Empfangen von Benachrichtigungen von SQL Server finden Sie weiter.

Konfigurieren von Benachrichtigungen mithilfe des WCF-Dienstmodells

Um die Benachrichtigungen mithilfe des WCF-Dienstmodells zu empfangen, müssen Sie:

  1. Generieren Sie einen WCF-Dienstvertrag (Schnittstelle) für den Benachrichtigungsvorgang aus den Metadaten, die vom Adapter verfügbar gemacht werden. Dazu können Sie das Add Adapter Service Reference Plug-In verwenden.

  2. Generieren Sie einen WCF-Client für den Select-Vorgang in der Tabelle Employee. Dazu können Sie das Add Adapter Service Reference Plug-In verwenden.

  3. Implementieren Sie über diese Schnittstelle einen WCF-Dienst.

  4. Hosten Sie diesen WCF-Dienst mithilfe eines Diensthosts (System.ServiceModel.ServiceHost).

Informationen zu den in diesem Thema verwendeten Beispielen

Die Beispiele in diesem Thema erhalten eine Benachrichtigung für die Tabelle Employee. Mit den Beispielen wird ein Skript zum Generieren der Tabelle bereitgestellt. Weitere Informationen zu den Beispielen finden Sie unter Beispiele für den SQL-Adapter. Ein Beispiel , Notification_ServiceModel, das auf diesem Thema basiert, wird auch mit den SQL-Adapterbeispielen bereitgestellt.

Wcf-Dienstvertrag und -Klasse

Sie können das Add Adapter Service Reference Plug-In verwenden, um einen WCF-Dienstvertrag (Schnittstelle) und unterstützende Klassen für den Benachrichtigungsvorgang zu erstellen. Weitere Informationen zum Generieren eines WCF-Dienstvertrags finden Sie unter Generieren eines WCF-Clients oder eines WCF-Dienstvertrags für SQL Server Artefakte.

Wcf-Dienstvertrag (Schnittstelle)

Der folgende Code zeigt den WCF-Dienstvertrag (Schnittstelle), der für den Benachrichtigungsvorgang generiert wurde.

[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);
}

Nachrichtenverträge

Im Folgenden ist der Nachrichtenvertrag für den Benachrichtigungsvorgang aufgeführt.

[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-Dienstklasse

Das Add Adapter Service Reference Plug-In generiert auch eine Datei, die einen Stub für die WCF-Dienstklasse aus dem Dienstvertrag (Schnittstelle) implementiert hat. Der Name der Datei lautet SqlAdapterBindingService.cs. Sie können die Logik zum Verarbeiten des Benachrichtigungsvorgangs direkt in diese Klasse einfügen. Der folgende Code zeigt die WCF-Dienstklasse, die vom Add Adapter Service Reference Plug-In generiert wurde.

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.");
        }
    }
}

Empfangen von Abfragebenachrichtigungen mithilfe des WCF-Dienstmodells

Dieser Abschnitt enthält Anweisungen zum Schreiben einer .NET-Anwendung zum Empfangen von Abfragebenachrichtigungen mithilfe des SQL-Adapters.

So empfangen Sie Abfragebenachrichtigungen

  1. Verwenden Sie das Add Adapter Service Reference Plug-In , um einen WCF-Client für den Select-Vorgang in der Tabelle Employee zu generieren. Sie verwenden diesen Client, um Select-Vorgänge auszuführen, nachdem sie eine Benachrichtigung erhalten haben. Fügen Sie Ihrem Projekt die neue Klasse TableOperation.cs hinzu, und fügen Sie den folgenden Codeausschnitt hinzu, um einen Select-Vorgang auszuführen.

    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("********************************************");
    
    

    Wichtig

    Da dieser Codeausschnitt Vorgänge für die Tabelle Employee ausführt, die eine Punkt-UDT-Spalte enthält, stellen Sie sicher, dass Sie die UDT-DLL unter dem Ordner \bin\Debug des Projekts platzieren, während Sie die Anwendung ausführen.

  2. Verwenden Sie das Add Adapter Service Reference Plug-In, um einen WCF-Dienstvertrag (Schnittstelle) und Hilfsklassen für den Benachrichtigungsvorgang zu generieren.

    Weitere Informationen finden Sie unter Generieren eines WCF-Clients oder WCF-Dienstvertrags für SQL Server Artefakte. Optional können Sie die Bindungseigenschaften beim Generieren des Dienstvertrags und der Hilfsklassen angeben. Dadurch wird sichergestellt, dass sie in der generierten Konfigurationsdatei ordnungsgemäß festgelegt werden.

  3. Implementieren Sie einen WCF-Dienst aus der In Schritt 2 generierten Schnittstellen- und Hilfsklassen. Die Notification-Methode dieser Klasse kann eine Ausnahme auslösen, um den Vorgang abzubrechen, wenn ein Fehler bei der Verarbeitung der vom Benachrichtigungsvorgang empfangenen Daten auftritt. andernfalls gibt die Methode nichts zurück. Sie müssen die WCF-Dienstklasse wie folgt zuordnen:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    

    Innerhalb der Benachrichtigungsmethode können Sie Ihre Anwendungslogik direkt implementieren. Diese Klasse finden Sie unter SqlAdapterBindingService.cs. Dieser Code in diesem Beispiel unterordnet die SqlAdapterBindingService-Klasse . In diesem Code wird die empfangene Benachrichtigungsnachricht in die Konsole geschrieben. Darüber hinaus wird die TableOp-Methode innerhalb der TableOperation-Klasse aufgerufen, um den Select-Vorgang auszuführen.

    [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();
        }
    }
    
  4. Da der SQL-Adapter keine Anmeldeinformationen als Teil des Verbindungs-URI akzeptiert, müssen Sie die folgende Klasse implementieren, um Anmeldeinformationen für die SQL Server Datenbank zu übergeben. Im letzteren Teil der Anwendung instanziieren Sie diese Klasse, um die SQL Server Anmeldeinformationen zu übergeben.

    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;
        }
    }
    
  5. Erstellen Sie eine SqlAdapterBinding-Instanz , und konfigurieren Sie den Adapter für den Empfang von Abfragebenachrichtigungen, indem Sie die Bindungseigenschaften angeben. Sie können dies entweder explizit im Code oder deklarativ in der Konfiguration tun. Mindestens müssen Sie die Bindungseigenschaften InboundOperationType und NotificationStatement angeben.

    SqlAdapterBinding binding = new SqlAdapterBinding();
    binding.InboundOperationType = InboundOperation.Notification;
    binding.NotificationStatement = "SELECT Employee_ID, Name FROM dbo.Employee WHERE Status=0";
    binding.NotifyOnListenerStart = true;
    
  6. Geben Sie SQL Server Datenbankanmeldeinformationen an, indem Sie die NotificationCredentials-Klasse instanziieren, die Sie in Schritt 4 erstellt haben.

    NotificationCredentials credentials = new NotificationCredentials();
    credentials.UserName.UserName = "<Enter user name here>";
    credentials.UserName.Password = "<Enter password here>";
    
  7. Erstellen Sie eine instance des WCF-Diensts, der in Schritt 3 erstellt wurde.

    // create service instance
    NotificationService service = new NotificationService();
    
  8. Erstellen Sie eine instance von System.ServiceModel.ServiceHost mithilfe des WCF-Diensts und eines Basisverbindungs-URI. Sie müssen hier auch die Anmeldeinformationen angeben.

    // Enable service host
    Uri[] baseUri = new Uri[] { new Uri("mssql://mysqlserver//mydatabase") };
    ServiceHost serviceHost = new ServiceHost(service, baseUri);
    serviceHost.Description.Behaviors.Add(credentials);
    
    
  9. Fügen Sie dem Diensthost einen Dienstendpunkt hinzu. Gehen Sie dazu folgendermaßen vor:

    • Verwenden Sie die in Schritt 5 erstellte Bindung.

    • Geben Sie einen Verbindungs-URI an, der Anmeldeinformationen und ggf. eine eingehende ID enthält.

    • Geben Sie den Vertrag als "NotificationOperation" an.

      // Add service endpoint: be sure to specify NotificationOperation as the contract
      Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?");
      serviceHost.AddServiceEndpoint("NotificationOperation", binding, ConnectionUri);
      
  10. Um eine Benachrichtigung zu erhalten, öffnen Sie den Diensthost.

    // Open the service host to begin receiving notifications
    serviceHost.Open();
    
  11. Um den Empfang von Benachrichtigungen zu beenden, schließen Sie den Diensthost.

    serviceHost.Close();
    

Beispiel

Das folgende Beispiel zeigt eine .NET-Anwendung zum Empfangen von Benachrichtigungen für die Tabelle Employee.

Hinweis

Der folgende Codeausschnitt instanziiert eine TableOperation.cs-Klasse und ruft die TableOp-Methode auf. Die -Klasse und die -Methode werden in Schritt 1 beschrieben.

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();
            }
        }
    }
}

Weitere Informationen

Entwickeln von SQL-Anwendungen mithilfe des WCF-Dienstmodells