Partager via


Recevoir des notifications de requête de SQL à l’aide du modèle de service WCF

Cette rubrique montre comment configurer l’adaptateur SQL pour recevoir des messages de notification de requête à partir d’une base de données SQL Server. Pour illustrer les notifications, envisagez une table, Employee, avec une colonne « Status ». Lorsqu’un nouvel enregistrement est inséré dans cette table, la valeur de la colonne État est définie sur 0. Vous pouvez configurer l’adaptateur pour recevoir des notifications en vous inscrivant aux notifications à l’aide d’une instruction SQL qui récupère tous les enregistrements dont la colonne État est « 0 ». Pour ce faire, spécifiez l’instruction SQL pour la propriété de liaison NotificationStatement . Une fois que le client d’adaptateur a reçu la notification, il peut contenir la logique permettant d’effectuer les tâches suivantes sur la base de données SQL Server. Dans cet exemple, par souci de simplicité, le client d’adaptateur répertorie tous les enregistrements de la table qui ont la colonne État comme « 0 ».

Notes

Si vous effectuez une opération sur des tables qui ont des colonnes de types définis par l’utilisateur, veillez à faire référence à Opérations sur les tables et les vues avec des types définis par l’utilisateur à l’aide de la rubrique adaptateur SQL avant de commencer à développer votre application.

Configuration des notifications avec les propriétés de liaison de l’adaptateur SQL

Le tableau suivant récapitule les propriétés de liaison de l’adaptateur SQL que vous utilisez pour configurer la réception de notifications à partir de SQL Server. Vous devez spécifier ces propriétés de liaison lors de l’exécution de l’application .NET pour recevoir les notifications d’une base de données SQL Server.

Binding, propriété Description
InboundOperationType Spécifie l’opération entrante que vous souhaitez effectuer. Pour recevoir des messages de notification, définissez-le sur Notification.
NotificationStatement Spécifie l’instruction SQL (procédure> stockée SELECT ou EXEC<) utilisée pour l’inscription aux notifications de requête. L’adaptateur reçoit un message de notification de SQL Server uniquement lorsque le jeu de résultats de l’instruction SQL spécifiée change.
NotifyOnListenerStart Spécifie si l’adaptateur envoie une notification aux clients de l’adaptateur lorsque l’écouteur est démarré.

Pour obtenir une description plus complète de ces propriétés, consultez En savoir plus sur les propriétés de liaison de l’adaptateur BizTalk pour SQL Server. Pour obtenir une description complète de l’utilisation de l’adaptateur SQL pour recevoir des notifications de SQL Server, lisez plus loin.

Configuration des notifications à l’aide du modèle de service WCF

Pour recevoir les notifications à l’aide du modèle de service WCF, vous devez :

  1. Générez un contrat de service WCF (interface) pour l’opération notification à partir des métadonnées exposées par l’adaptateur. Pour ce faire, vous pouvez utiliser le plug-in Add Adapter Service Reference.

  2. Générez un client WCF pour l’opération Sélectionner sur la table Employee. Pour ce faire, vous pouvez utiliser le plug-in Add Adapter Service Reference.

  3. Implémentez un service WCF à partir de cette interface.

  4. Hébergez ce service WCF à l’aide d’un hôte de service (System.ServiceModel.ServiceHost).

À propos des exemples utilisés dans cette rubrique

Les exemples de cette rubrique reçoivent une notification pour la table Employee. Un script pour générer la table est fourni avec les exemples. Pour plus d’informations sur les exemples, consultez Exemples pour l’adaptateur SQL. Un exemple, Notification_ServiceModel, basé sur cette rubrique, est également fourni avec les exemples d’adaptateur SQL.

Contrat et classe de service WCF

Vous pouvez utiliser le plug-in Add Adapter Service Reference pour créer un contrat de service WCF (interface) et des classes de prise en charge pour l’opération notification . Pour plus d’informations sur la génération d’un contrat de service WCF, consultez Générer un client WCF ou un contrat de service WCF pour SQL Server Artefacts.

Contrat de service WCF (interface)

Le code suivant montre le contrat de service WCF (interface) généré pour l’opération notification .

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

Contrats de message

Voici le contrat de message pour l’opération de notification.

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

Classe de service WCF

Le plug-in Add Adapter Service Reference génère également un fichier qui a un stub pour la classe de service WCF implémentée à partir du contrat de service (interface). Le nom du fichier est SqlAdapterBindingService.cs. Vous pouvez insérer la logique pour traiter l’opération Notification directement dans cette classe. Le code suivant montre la classe de service WCF générée par le plug-in Add Adapter Service Reference.

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

Réception de notifications de requête à l’aide du modèle de service WCF

Cette section fournit des instructions sur la façon d’écrire une application .NET pour recevoir des notifications de requête à l’aide de l’adaptateur SQL.

Pour recevoir des notifications de requête

  1. Utilisez le plug-in Add Adapter Service Reference pour générer un client WCF pour l’opération Select sur la table Employee . Vous allez utiliser ce client pour effectuer des opérations De sélection après avoir reçu un message de notification. Ajoutez une nouvelle classe, TableOperation.cs, à votre projet et ajoutez l’extrait de code suivant pour effectuer une opération 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("********************************************");
    
    

    Important

    Étant donné que cet extrait de code effectue des opérations sur la table Employee qui contient une colonne Point UDT, veillez à placer la DLL UDT sous le dossier \bin\Debug du projet lors de l’exécution de l’application.

  2. Utilisez le plug-in Add Adapter Service Reference pour générer un contrat de service WCF (interface) et des classes d’assistance pour l’opération de notification .

    Pour plus d’informations, consultez Générer un client WCF ou un contrat de service WCF pour SQL Server Artefacts. Vous pouvez éventuellement spécifier les propriétés de liaison lors de la génération du contrat de service et des classes d’assistance. Cela garantit qu’ils sont correctement définis dans le fichier de configuration généré.

  3. Implémentez un service WCF à partir des classes d’interface et d’assistance générées à l’étape 2. La méthode Notification de cette classe peut lever une exception pour annuler l’opération, si une erreur est rencontrée lors du traitement des données reçues de l’opération Notification ; sinon, la méthode ne retourne rien. Vous devez attribuer la classe de service WCF comme suit :

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    

    Dans la méthode Notification , vous pouvez implémenter directement votre logique d’application. Cette classe se trouve dans SqlAdapterBindingService.cs. Ce code dans cet exemple sous-classe la classe SqlAdapterBindingService . Dans ce code, le message de notification reçu est écrit dans la console. En outre, la méthode TableOp dans la classe TableOperation est appelée pour effectuer l’opération Select.

    [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. Étant donné que l’adaptateur SQL n’accepte pas les informations d’identification dans le cadre de l’URI de connexion, vous devez implémenter la classe suivante pour transmettre les informations d’identification pour la base de données SQL Server. Dans la dernière partie de l’application, vous allez instancier cette classe pour transmettre les informations d’identification 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;
        }
    }
    
  5. Créez un SqlAdapterBinding et configurez l’adaptateur pour recevoir des notifications de requête en spécifiant les propriétés de liaison. Vous pouvez effectuer cette opération de manière explicite dans le code ou de manière déclarative dans la configuration. Au minimum, vous devez spécifier les propriétés de liaison InboundOperationType et NotificationStatement .

    SqlAdapterBinding binding = new SqlAdapterBinding();
    binding.InboundOperationType = InboundOperation.Notification;
    binding.NotificationStatement = "SELECT Employee_ID, Name FROM dbo.Employee WHERE Status=0";
    binding.NotifyOnListenerStart = true;
    
  6. Spécifiez SQL Server informations d’identification de base de données en instanciant la classe NotificationCredentials que vous avez créée à l’étape 4.

    NotificationCredentials credentials = new NotificationCredentials();
    credentials.UserName.UserName = "<Enter user name here>";
    credentials.UserName.Password = "<Enter password here>";
    
  7. Créez un instance du service WCF créé à l’étape 3.

    // create service instance
    NotificationService service = new NotificationService();
    
  8. Créez un instance de System.ServiceModel.ServiceHost à l’aide du service WCF et d’un URI de connexion de base. Vous devez également spécifier les informations d’identification ici.

    // Enable service host
    Uri[] baseUri = new Uri[] { new Uri("mssql://mysqlserver//mydatabase") };
    ServiceHost serviceHost = new ServiceHost(service, baseUri);
    serviceHost.Description.Behaviors.Add(credentials);
    
    
  9. Ajoutez un point de terminaison de service à l’hôte de service. Pour ce faire :

    • Utilisez la liaison créée à l’étape 5.

    • Spécifiez un URI de connexion qui contient des informations d’identification et, si nécessaire, un ID entrant.

    • Spécifiez le contrat comme « NotificationOperation ».

      // Add service endpoint: be sure to specify NotificationOperation as the contract
      Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?");
      serviceHost.AddServiceEndpoint("NotificationOperation", binding, ConnectionUri);
      
  10. Pour recevoir un message de notification, ouvrez l’hôte de service.

    // Open the service host to begin receiving notifications
    serviceHost.Open();
    
  11. Pour arrêter de recevoir des notifications, fermez l’hôte de service.

    serviceHost.Close();
    

Exemple

L’exemple suivant montre une application .NET pour recevoir des messages de notification pour la table Employee.

Notes

L’extrait de code suivant instancie une classe TableOperation.cs et appelle la méthode TableOp . La classe et la méthode sont décrites à l’étape 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();
            }
        }
    }
}

Voir aussi

Développer des applications SQL à l’aide du modèle de service WCF