Condividi tramite


Ricevere messaggi di modifica dei dati basati sul polling da SQL Server usando il modello di canale WCF

È possibile configurare l'adapter SQL per ricevere messaggi periodici di modifica dei dati per tabelle o viste di SQL Server. È possibile specificare un'istruzione di polling eseguita dall'adapter per eseguire il polling del database. L'istruzione di polling può essere un'istruzione SELECT o una stored procedure che restituisce un insieme di risultati.

Per altre informazioni su come l'adapter supporta il polling, vedere Supporto per le chiamate in ingresso tramite polling.

Importante

Se si desidera avere più di un'operazione di polling in una singola applicazione, è necessario specificare una proprietà di connessione InboundID come parte dell'URI di connessione per renderla univoca. L'ID in ingresso specificato viene aggiunto allo spazio dei nomi dell'operazione per renderlo unico.

Come questo argomento dimostra il polling

In questo argomento, per illustrare come l'adapter SQL supporta la ricezione di messaggi di modifica dei dati, crea un'applicazione .NET per l'operazione di polling. Per questo argomento, specificare PolledDataAvailableStatement come:

SELECT COUNT(*) FROM Employee  

PolledDataAvailableStatement deve restituire un set di risultati con la prima cella contenente un valore positivo. Se la prima cella non contiene un valore positivo, l'adapter non esegue l'istruzione di polling.

Come parte dell'istruzione di polling, eseguire le operazioni seguenti:

  1. Selezionare tutte le righe dalla tabella Employee.

  2. Eseguire una procedura memorizzata (MOVE_EMP_DATA) per spostare tutti i record dalla tabella Employee a una tabella EmployeeHistory.

  3. Eseguire una procedura memorizzata (ADD_EMP_DETAILS) per aggiungere un nuovo record alla tabella Dipendente. Questa procedura accetta come parametri il nome, la designazione e lo stipendio del dipendente.

    Per eseguire queste operazioni, è necessario specificare quanto segue per la proprietà di associazione PollingStatement :

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

Dopo l'esecuzione dell'istruzione di polling, vengono selezionati tutti i record della tabella Employee e viene ricevuto il messaggio da SQL Server. Dopo che la stored procedure MOVE_EMP_DATA viene eseguita dall'adapter, tutti i record vengono spostati nella tabella EmployeeHistory. Viene quindi eseguita la stored procedure ADD_EMP_DETAILS per aggiungere un nuovo record alla tabella Employee. L'esecuzione di polling successiva restituirà solo un singolo record. Questo ciclo continua fino a quando non si chiude il listener del canale.

Configurazione di una query di polling con le proprietà di associazione dell'adapter SQL

La tabella seguente riepiloga le proprietà di associazione dell'adapter SQL usate per configurare l'adapter per ricevere messaggi di modifica dei dati. È necessario specificare queste proprietà di associazione come parte dell'applicazione .NET per il polling.

Proprietà di associazione Descrizione
InboundOperationType Specifica se si desidera eseguire l'operazione polling, TypedPolling o Notifica in ingresso. Il valore predefinito è Polling.
PolledDataAvailableStatement Specifica l'istruzione SQL eseguita dall'adapter per determinare se sono disponibili dati per il polling. L'istruzione SQL deve restituire un set di risultati costituito da righe e colonne. Solo se è disponibile una riga, verrà eseguita l'istruzione SQL specificata per la proprietà di associazione PollingStatement .
PollingIntervalInSeconds Specifica l'intervallo, espresso in secondi, in cui l'adapter SQL esegue l'istruzione specificata per la proprietà di associazione PolledDataAvailableStatement . Il valore predefinito è 30 secondi. L'intervallo di polling determina l'intervallo di tempo tra i sondaggi successivi. Se l'istruzione viene eseguita entro l'intervallo specificato, l'adattatore attende il tempo rimanente nell'intervallo.
PollingStatement Specifica l'istruzione SQL per eseguire il polling della tabella di database di SQL Server. È possibile specificare una semplice istruzione SELECT o una stored procedure per l'istruzione di polling. Il valore predefinito è Null. Per abilitare il polling, è necessario specificare un valore per PollingStatement . L'istruzione di polling viene eseguita solo se sono disponibili dati per il polling, il che è determinato dalla proprietà di associazione PolledDataAvailableStatement. È possibile specificare un numero qualsiasi di istruzioni SQL separate da un punto e virgola.
PollWhileDataFound Specifica se l'adapter SQL ignora l'intervallo di polling ed esegue continuamente l'istruzione SQL specificata per la proprietà di associazione PolledDataAvailableStatement , se i dati sono disponibili nella tabella di cui viene eseguito il polling. Se nella tabella non sono disponibili dati, l'adapter torna a eseguire l'istruzione SQL all'intervallo di polling specificato. Il valore predefinito è false.

Per una descrizione più completa di queste proprietà, vedere Informazioni sulle proprietà di associazione dell'adapter BizTalk per SQL Server. Per una descrizione completa di come usare l'adapter SQL per eseguire il polling di SQL Server, leggere il resto di questo argomento.

Utilizzo del messaggio di richiesta di polling

L'adattatore richiama l'operazione Polling nel tuo codice per interrogare il database di SQL Server. Ovvero, l'adapter invia un messaggio di richiesta di interrogazione che ricevi tramite un tipo di canale IInputChannel. Il messaggio di richiesta di polling contiene il set di risultati della query specificata dalla proprietà di associazione PollingStatement. È possibile utilizzare il messaggio di polling in uno dei due modi seguenti:

  • Per utilizzare il messaggio usando il flusso node-value, è necessario chiamare il metodo WriteBodyContents nel messaggio di risposta e passarlo a xmlDictionaryWriter che implementa il flusso node-value.

  • Per utilizzare il messaggio usando lo streaming dei nodi, è possibile chiamare GetReaderAtBodyContents nel messaggio di risposta per ottenere un XmlReader.

Informazioni sugli esempi usati in questo argomento

Negli esempi di questo argomento si interrogano i dati della tabella Employee. L'esempio usa anche le procedure memorizzate MOVE_EMP_DATA e ADD_EMP_DETAILS. Uno script per generare questi artefatti viene fornito con gli esempi. Per altre informazioni sugli esempi, vedere Esempi per l'adapter SQL. Un esempio, Polling_ChannelModel, basato su questo argomento, viene fornito anche con gli esempi dell'adapter SQL.

Ricezione di messaggi in ingresso per l'operazione di polling tramite il modello di canale WCF

Questa sezione fornisce istruzioni su come scrivere un'applicazione .NET (modello di canale) per ricevere messaggi di polling in ingresso tramite l'adapter SQL.

Per ricevere messaggi di polling dall'adapter SQL

  1. Creare un progetto Microsoft Visual C# in Visual Studio. Per questo argomento, creare un'applicazione console.

  2. In Esplora soluzioni aggiungere il riferimento a Microsoft.Adapters.Sql, Microsoft.ServiceModel.Channels, System.ServiceModele System.Runtime.Serialization.

  3. Aprire il file Program.cs e aggiungere i seguenti namespace:

    • Microsoft.Adapters.Sql

    • System.ServiceModel

    • System.ServiceModel.Description

    • System.ServiceModel.Channels

    • System.Xml

  4. Specificare un URI di connessione. Per ulteriori informazioni sull'URI di connessione dell'adattatore, consultare Creare l'URI di connessione di SQL Server.

    Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?");  
    
  5. Creare un'istanza di SqlAdapterBinding e impostare le proprietà di associazione necessarie per configurare il polling. È necessario impostare almeno le proprietà di associazione InboundOperationType, PolledDataAvailableStatement e PollingStatement . Per altre informazioni sulle proprietà di associazione usate per configurare il polling, vedere Supporto per le chiamate in ingresso tramite polling.

    SqlAdapterBinding binding = new SqlAdapterBinding();  
    binding.InboundOperationType = InboundOperation.Polling;  
    binding.PolledDataAvailableStatement = "SELECT COUNT (*) FROM EMPLOYEE";  
    binding.PollingStatement = "SELECT * FROM Employee;EXEC MOVE_EMP_DATA;EXEC ADD_EMP_DETAILS John, Tester, 100000";  
    
  6. Creare una raccolta di parametri di associazione e impostare le credenziali.

    ClientCredentials credentials = new ClientCredentials();  
    credentials.UserName.UserName = "<Enter user name here>";  
    credentials.UserName.Password = "<Enter password here>";  
    
    BindingParameterCollection bindingParams = new BindingParameterCollection();  
    bindingParams.Add(credentials);  
    
  7. Creare un listener del canale e aprirlo. Per creare il listener, invocare il metodo BuildChannelListener<IInputChannel> su SqlAdapterBinding.

    IChannelListener<IInputChannel> listener = binding.BuildChannelListener<IInputChannel>(connectionUri, bindingParams);  
    listener.Open();  
    
  8. Ottenere un canale IInputChannel richiamando il metodo AcceptChannel nel listener e aprirlo.

    IInputChannel channel = listener.AcceptChannel();  
    channel.Open();  
    
  9. Richiamare Receive sul canale per ottenere il successivo messaggio POLLINGSTMT dall'adapter.

    Message message = channel.Receive();  
    
  10. Consumare il set di risultati restituito dall'operazione POLLINGSTMT. È possibile utilizzare il messaggio usando xmlReader o XmlDictionaryWriter.

    XmlReader reader = message.GetReaderAtBodyContents();  
    
  11. Chiudere il canale dopo aver completato l'elaborazione della richiesta.

    channel.Close()  
    

    Importante

    Dopo aver completato l'elaborazione dell'operazione POLLINGSTMT, è necessario chiudere il canale. La mancata chiusura del canale può influire sul comportamento del codice.

  12. Chiudi il listener quando hai finito di ricevere messaggi di variazione dei dati.

    listener.Close()  
    

    Importante

    La chiusura del listener non chiude i canali creati usando il listener. È necessario chiudere in modo esplicito ogni canale creato usando il listener.

Esempio

Nell'esempio seguente viene illustrata una query di polling che interroga la tabella denominata Employee. L'istruzione di polling esegue le attività seguenti:

  • Seleziona tutti i record dalla tabella Employee.

  • Esegue la stored procedure MOVE_EMP_DATA per spostare tutti i record dalla tabella Employee alla tabella EmployeeHistory.

  • Esegue la stored procedure ADD_EMP_DETAILS per aggiungere un singolo record alla tabella Employee.

    I messaggi di polling vengono salvati in C:\PollingOutput.xml.

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

using System.Xml;  

namespace ConsoleApplication1  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            Console.WriteLine("Sample started. This sample will poll 5 times and will perform the following tasks:");  
            Console.WriteLine("Press any key to start polling...");  
            Console.ReadLine();  
            IChannelListener<IInputChannel> listener = null;  

            IInputChannel channel = null;  

            try  
            {  
                TimeSpan messageTimeout = new TimeSpan(0, 0, 30);  

                SqlAdapterBinding binding = new SqlAdapterBinding();  
                binding.InboundOperationType = InboundOperation.Polling;  
                binding.PolledDataAvailableStatement = "SELECT COUNT (*) FROM EMPLOYEE";  
                binding.PollingStatement = "SELECT * FROM Employee;EXEC MOVE_EMP_DATA;EXEC ADD_EMP_DETAILS John, Tester, 100000";  

                Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?");  

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

                BindingParameterCollection bindingParams = new BindingParameterCollection();  
                bindingParams.Add(credentials);  

                listener = binding.BuildChannelListener<IInputChannel>(ConnectionUri, bindingParams);  
                listener.Open();  

                channel = listener.AcceptChannel();  
                channel.Open();  

                Console.WriteLine("Channel and Listener opened...");  
                Console.WriteLine("\nWaiting for polled data...");  
                Console.WriteLine("Receive request timeout is {0}", messageTimeout);  

                // Poll five times with the specified message timeout   
                // If a timeout occurs polling will be aborted  
                for (int i = 0; i < 5; i++)  
                {  
                    Console.WriteLine("Polling: " + i);  
                    Message message = null;  
                    XmlReader reader = null;  
                    try  
                    {  
                        //Message is received so process the results  
                        message = channel.Receive(messageTimeout);  
                    }  
                    catch (System.TimeoutException toEx)  
                    {  
                        Console.WriteLine("\nNo data for request number {0}: {1}", i + 1, toEx.Message);  
                        continue;  
                    }  

                    // Get the query results using an XML reader  
                    try  
                    {  
                        reader = message.GetReaderAtBodyContents();  
                    }  
                    catch (Exception ex)  
                    {  
                        Console.WriteLine("Exception :" + ex);  
                        throw;  
                    }  

                    XmlDocument doc = new XmlDocument();  
                    doc.Load(reader);  
                    using (XmlWriter writer = XmlWriter.Create("C:\\PollingOutput.xml"))  
                    {  
                        doc.WriteTo(writer);  
                        Console.WriteLine("The polling response is saved at 'C:\\PollingOutput.xml'");  
                    }  

                    // return the cursor  
                    Console.WriteLine();  

                    // close the reader  
                    reader.Close();  

                    message.Close();  
                }  
                Console.WriteLine("\nPolling done -- hit <RETURN> to finish");  
                Console.ReadLine();  
            }  
            catch (Exception ex)  
            {  
                Console.WriteLine("Exception is: " + ex.Message);  
                if (ex.InnerException != null)  
                {  
                    Console.WriteLine("Inner Exception is: " + ex.InnerException.Message);  
                }  
            }  
            finally  
            {  
                // IMPORTANT: close the channel and listener to stop polling  
                if (channel != null)  
                {  
                    if (channel.State == CommunicationState.Opened)  
                        channel.Close();  
                    else  
                        channel.Abort();  
                }  

                if (listener != null)  
                {  
                    if (listener.State == CommunicationState.Opened)  
                        listener.Close();  
                    else  
                        listener.Abort();  
                }  
            }  
        }  
    }  
}  

Vedere anche

Sviluppare applicazioni SQL usando il modello di canale WCF