Ricevere messaggi modificati in base al polling da SQL Server tramite il modello di canale WCF
È possibile configurare l'adapter SQL per ricevere messaggi periodici di modifica dei dati per SQL Server tabelle o viste. È 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 set di risultati.
Per altre informazioni sul modo in cui l'adapter supporta il polling, vedere Supporto per le chiamate in ingresso tramite polling.
Importante
Se si desidera avere più operazioni di polling in una singola applicazione, è necessario specificare una proprietà di connessione InboundID come parte dell'URI di connessione per renderlo univoco. L'ID in ingresso specificato viene aggiunto allo spazio dei nomi dell'operazione per renderlo univoco.
Come viene illustrato il polling di questo argomento
In questo argomento viene illustrato come l'adapter SQL supporta la ricezione di messaggi di modifica dei dati, creare un'applicazione .NET per l'operazione 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.
Nell'ambito dell'istruzione di polling eseguire le operazioni seguenti:
Selezionare tutte le righe dalla tabella Employee.
Eseguire una stored procedure (MOVE_EMP_DATA) per spostare tutti i record dalla tabella Employee a una tabella EmployeeHistory.
Eseguire una stored procedure (ADD_EMP_DETAILS) per aggiungere un nuovo record alla tabella Employee. Questa procedura accetta il nome, la designazione e lo stipendio dei dipendenti come parametri.
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 aver eseguito la stored procedure MOVE_EMP_DATA 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 del polling successivo restituirà solo un singolo record. Questo ciclo continua fino a chiudere il listener del canale.
Configurazione di una query di polling con le proprietà di associazione dell'adapter SQL
Nella tabella seguente vengono riepilogate 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.
Binding, proprietà | 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 i dati sono disponibili 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, 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 polling successivi. Se l'istruzione viene eseguita all'interno dell'intervallo specificato, l'adapter attende il tempo rimanente nell'intervallo. |
PollingStatement | Specifica l'istruzione SQL per eseguire il polling della tabella di database SQL Server. È possibile specificare un'istruzione SELECT semplice o una stored procedure per l'istruzione di polling. Il valore predefinito è Null. È necessario specificare un valore per PollingStatement per abilitare il polling. L'istruzione polling viene eseguita solo se sono disponibili dati per il polling, che viene determinato dalla proprietà di associazione PolledDataAvailableStatement . È possibile specificare qualsiasi numero 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 in cui viene eseguito il polling. Se nella tabella non sono disponibili dati, l'adapter esegue l'istruzione SQL all'intervallo di polling specificato. Il valore predefinito è false. |
Per una descrizione più completa di queste proprietà, vedere Informazioni sull'adapter BizTalk per le proprietà di associazione dell'adapter SQL Server. Per una descrizione completa di come usare l'adapter SQL per eseguire il polling di SQL Server, leggere la parte restante di questo argomento.
Utilizzo del messaggio di richiesta di polling
L'adapter richiama l'operazione polling nel codice per eseguire il polling del database SQL Server. Ovvero, l'adapter invia un messaggio di richiesta polling che viene visualizzato tramite una forma di canale IInputChannel. Il messaggio di richiesta polling contiene il set di risultati della query specificata dalla proprietà di associazione PollingStatement. È possibile usare il messaggio 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 un oggetto XmlDictionaryWriter che implementa lo streaming node-value.
Per utilizzare il messaggio usando il flusso del nodo, è possibile chiamare GetReaderAtBodyContents nel messaggio di risposta per ottenere un xmlReader.
Informazioni sugli esempi usati in questo argomento
Gli esempi in questo argomento eseguano il polling della tabella Employee. L'esempio usa anche la stored procedure 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'adattatore SQL.
Ricezione di messaggi in ingresso per l'operazione di polling usando il modello di canale WCF
In questa sezione vengono fornite 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
Creare un progetto Microsoft Visual C# in Visual Studio. Per questo argomento, creare un'applicazione console.
Nella Esplora soluzioni aggiungere riferimento a
Microsoft.Adapters.Sql
,Microsoft.ServiceModel.Channels
,System.ServiceModel
eSystem.Runtime.Serialization
.Aprire il file Program.cs e aggiungere gli spazi dei nomi seguenti:
Microsoft.Adapters.Sql
System.ServiceModel
System.ServiceModel.Description
System.ServiceModel.Channels
System.Xml
Specificare un URI di connessione. Per altre informazioni sull'URI di connessione della scheda, vedere Creare l'URI di connessione SQL Server.
Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?");
Creare un'istanza di SqlAdapterBinding e impostare le proprietà di associazione necessarie per configurare il polling. Almeno è necessario impostare 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";
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);
Creare un listener del canale e aprirlo. Si crea il listener richiamando il metodo BuildChannelListener<IInputChannel> in SqlAdapterBinding.
IChannelListener<IInputChannel> listener = binding.BuildChannelListener<IInputChannel>(connectionUri, bindingParams); listener.Open();
Ottenere un canale IInputChannel richiamando il metodo AcceptChannel nel listener e aprirlo.
IInputChannel channel = listener.AcceptChannel(); channel.Open();
Richiamare Ricezione nel canale per ottenere il messaggio POLLINGSTMT successivo dall'adapter.
Message message = channel.Receive();
Utilizzare il set di risultati restituito dall'operazione POLLINGSTMT. È possibile utilizzare il messaggio usando xmlReader o xmlDictionaryWriter.
XmlReader reader = message.GetReaderAtBodyContents();
Chiudere il canale al termine dell'elaborazione della richiesta.
channel.Close()
Importante
È necessario chiudere il canale dopo aver completato l'elaborazione dell'operazione POLLINGSTMT. L'errore di chiudere il canale può influire sul comportamento del codice.
Chiudere il listener al termine della ricezione di messaggi modificati dai 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 esegue la tabella Employee. L'istruzione di polling esegue le attività seguenti:
Seleziona tutti i record della 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();
}
}
}
}
}