Ricevere messaggi di modifica dei dati basati sul polling da SQL Server tramite il modello di servizio 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'adattatore 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 su come l'adapter supporta il polling, vedere Polling in SQL Server using the SQL adapter .For more information on how the adapter supports polling, see Polling in SQL Server using the SQL adapter.
Nota
In questo argomento viene illustrato come utilizzare l'operazione di polling in ingresso per usare i messaggi di polling. Il messaggio per l'operazione di polling non è fortemente tipizzato. Per ottenere un messaggio di polling fortemente tipizzato, è necessario utilizzare l'operazione TypedPolling . È inoltre necessario utilizzare l'operazione TypedPolling per eseguire più operazioni di polling in una singola applicazione. Per istruzioni su come eseguire l'operazione TypedPolling, vedere Ricevere messaggi di modifica dei dati basati su polling fortemente tipizzato da SQL Server tramite il modello di servizio WCF.
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 univoco.
Come illustra il polling in questo argomento
In questo argomento viene illustrato come l'adapter SQL supporta la ricezione di messaggi di modifica dei dati, creare un'applicazione .NET e generare il contratto di servizio WCF per l'operazione di polling . Se si desidera specificare le proprietà di associazione correlate al polling durante la generazione del contratto di servizio WCF, 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:
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 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 del polling successiva restituirà solo un singolo record. Questo ciclo continua fino a quando non si chiude l'host del servizio.
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 Notification 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, 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'adapter attende il tempo rimanente nell'intervallo. |
PollingStatement | Specifica l'istruzione SQL per eseguire il polling della tabella di database SQL Server. È possibile specificare una semplice istruzione SELECT 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 di polling viene eseguita solo se sono disponibili dati per il polling, determinato dalla proprietà di associazione PolledDataAvailableStatement . È possibile specificare un numero qualsiasi di istruzioni SQL separate da un punto e virgola. |
PollWhileDataFound | Specifica se l'adattatore 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 viene ripristinato per eseguire l'istruzione SQL in corrispondenza dell'intervallo di polling specificato. Il valore predefinito è false. |
Per una descrizione più completa di queste proprietà, vedere Informazioni sull'adapter BizTalk per SQL Server proprietà di associazione dell'adapter. Per una descrizione completa di come usare l'adapter SQL per eseguire il polling di SQL Server, leggere altre informazioni.
Configurazione del polling nel modello di servizio WCF
Per ricevere l'operazione polling quando si usa il modello di servizio WCF, è necessario:
Generare un contratto di servizio WCF (interfaccia) per l'operazione di polling dai metadati esposti dall'adattatore. A tale scopo, è possibile usare il plug-in Add Adapter Service Reference di Visual Studio.
Implementare un servizio WCF da questa interfaccia.
Ospitare questo servizio WCF usando un host del servizio (System.ServiceModel.ServiceHost).
Informazioni sugli esempi usati in questo argomento
Gli esempi in questo argomento eseguano il polling della tabella Employee. Nell'esempio vengono inoltre utilizzati il MOVE_EMP_DATA e ADD_EMP_DETAILS stored procedure. 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_ServiceModel, basato su questo argomento, viene fornito anche con gli esempi dell'adattatore SQL.
Classe e contratto di servizio WCF
È possibile usare il plug-in Aggiungi riferimento al servizio adapter per creare un contratto di servizio WCF (interfaccia) e le classi di supporto per l'operazione di polling . Per altre informazioni sulla generazione di un contratto di servizio WCF, vedere Generare un client WCF o un contratto di servizio WCF per SQL Server Artefatti.
Contratto di servizio WCF (interfaccia)
Il codice seguente mostra il contratto di servizio WCF (interfaccia) generato per l'operazione di polling .
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://schemas.microsoft.com/Sql/2008/05/", ConfigurationName="PollingOperation")]
public interface PollingOperation {
// CODEGEN: Generating message contract since the wrapper namespace (https://schemas.microsoft.com/Sql/2008/05/Polling/) of message Polling
// does not match the default value (https://schemas.microsoft.com/Sql/2008/05/)
[System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="Polling")]
[System.ServiceModel.XmlSerializerFormatAttribute()]
void Polling(Polling request);
}
Contratti di messaggio
Lo spazio dei nomi del contratto di messaggio viene modificato dal parametro InboundID nell'URI di connessione, se specificato. In questo esempio non è stato specificato un ID in ingresso nell'URI di connessione. Il messaggio di richiesta restituisce un oggetto DataSet.
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="Polling", WrapperNamespace="http://schemas.microsoft.com/Sql/2008/05/Polling/", IsWrapped=true)]
public partial class Polling {
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/Sql/2008/05/Polling/", Order=0)]
[System.Xml.Serialization.XmlArrayAttribute(IsNullable=true)]
[System.Xml.Serialization.XmlArrayItemAttribute("DataSet", Namespace="http://schemas.datacontract.org/2004/07/System.Data", IsNullable=false)]
public System.Data.DataSet[] PolledData;
public Polling() {
}
public Polling(System.Data.DataSet[] PolledData) {
this.PolledData = PolledData;
}
}
Classe di servizio WCF
Il plug-in Add Adapter Service Reference genera anche un file con uno stub per la classe di servizio WCF implementata dal contratto di servizio (interfaccia). Il nome del file è SqlAdapterBindingService.cs. È possibile inserire la logica per elaborare l'operazione di polling direttamente in questa classe. Il codice seguente mostra la classe del servizio WCF generata dal plug-in Add Adapter Service Reference.
namespace SqlAdapterBindingNamespace {
public class SqlAdapterBindingService : PollingOperation {
// CODEGEN: Generating message contract since the wrapper namespace (https://schemas.microsoft.com/Sql/2008/05/Polling/) of message Polling
// does not match the default value (https://schemas.microsoft.com/Sql/2008/05/)
public virtual void Polling(Polling request) {
throw new System.NotImplementedException("The method or operation is not implemented.");
}
}
}
Ricezione di messaggi in ingresso per l'operazione di polling
Questa sezione fornisce istruzioni su come scrivere un'applicazione .NET per ricevere messaggi di polling in ingresso usando l'adapter SQL.
Per ricevere messaggi di polling dall'adapter SQL
Usare il plug-in Add Adapter Service Reference per generare un contratto di servizio WCF (interfaccia) e classi helper per l'operazione di polling . Per altre informazioni, vedere Generare un client WCF o un contratto di servizio WCF per SQL Server artefatti. Facoltativamente, è possibile specificare le proprietà di associazione durante la generazione del contratto di servizio e delle classi helper. In questo modo si garantisce che siano impostati correttamente nel file di configurazione generato.
Implementare un servizio WCF dalle classi di interfaccia e helper generate nel passaggio 1. Il metodo Polling di questa classe può generare un'eccezione per interrompere la transazione di polling, se si verifica un errore durante l'elaborazione dei dati ricevuti dall'operazione di polling ; in caso contrario, il metodo non restituisce alcun elemento. È necessario attribuire la classe del servizio WCF come indicato di seguito:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
All'interno del metodo Polling è possibile implementare direttamente la logica dell'applicazione. Questa classe è disponibile in SqlAdapterBindingService.cs. Questo codice in questa sottoclasse di esempio esegue la classe SqlAdapterBindingService . In questo codice il messaggio di polling ricevuto come oggetto DataSet viene scritto nella console.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class PollingService : SqlAdapterBindingNamespace.SqlAdapterBindingService { public override void Polling(Polling request) { Console.WriteLine("\nNew Polling Records Received"); Console.WriteLine("*************************************************"); DataSet[] dataArray = request.PolledData; foreach (DataTable tab in dataArray[0].Tables) { foreach (DataRow row in tab.Rows) { for (int i = 0; i < tab.Columns.Count; i++) { Console.WriteLine(row[i]); } } } Console.WriteLine("*************************************************"); Console.WriteLine("\nHit <RETURN> to stop polling"); } }
Poiché l'adapter SQL non accetta le credenziali come parte dell'URI di connessione, è necessario implementare la classe seguente per passare le credenziali per il database SQL Server. Nella seconda parte dell'applicazione verrà creata un'istanza di questa classe per passare le credenziali di SQL Server.
class PollingCredentials : 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 PollingCredentials(); clone.UserName.UserName = this.UserName.UserName; clone.UserName.Password = this.UserName.Password; return clone; } }
Creare un oggetto SqlAdapterBinding e configurare l'operazione di polling specificando le proprietà di associazione. È possibile eseguire questa operazione in modo esplicito nel codice o in modo dichiarativo nella configurazione. Almeno, è necessario specificare InboundOperationType, PolledDataAvailableStatement e PollingStatement.
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";
Specificare SQL Server credenziali del database creando un'istanza della classe PollingCredentials creata nel passaggio 3.
PollingCredentials credentials = new PollingCredentials(); credentials.UserName.UserName = "<Enter user name here>"; credentials.UserName.Password = "<Enter password here>";
Creare un'istanza del servizio WCF creata nel passaggio 2.
// create service instance PollingService service = new PollingService();
Creare un'istanza di System.ServiceModel.ServiceHost usando il servizio WCF e un URI di connessione di base. L'URI di connessione di base non può contenere l'ID in ingresso, se specificato. È anche necessario specificare le credenziali qui.
// Enable service host Uri[] baseUri = new Uri[] { new Uri("mssql://mysqlserver//mydatabase") }; ServiceHost serviceHost = new ServiceHost(service, baseUri); serviceHost.Description.Behaviors.Add(credentials);
Aggiungere un endpoint di servizio all'host del servizio. Per eseguire questa operazione:
Usare l'associazione creata nel passaggio 4.
Specificare un URI di connessione contenente le credenziali e, se necessario, un ID in ingresso.
Specificare il contratto come "PollingOperation".
// Add service endpoint: be sure to specify PollingOperation as the contract Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?"); serviceHost.AddServiceEndpoint("PollingOperation", binding, ConnectionUri);
Per ricevere i dati di polling, aprire l'host del servizio. L'adapter restituirà i dati ogni volta che la query restituisce un set di risultati.
// Open the service host to begin polling serviceHost.Open();
Per terminare il polling, chiudere l'host del servizio.
Importante
L'adapter continuerà a eseguire il polling fino alla chiusura dell'host del servizio.
serviceHost.Close();
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.
Il primo messaggio di polling conterrà tutti i record della tabella Employee. I messaggi di polling successivi contengono solo l'ultimo record inserito dalla stored procedure ADD_EMP_DETAILS. L'adapter continuerà a eseguire il polling fino a chiudere l'host del servizio premendo
<RETURN>
.
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;
using System.Data;
namespace Polling_ServiceModel
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class PollingService : SqlAdapterBindingNamespace.SqlAdapterBindingService
{
public override void Polling(Polling request)
{
Console.WriteLine("\nNew Polling Records Received");
Console.WriteLine("*************************************************");
DataSet[] dataArray = request.PolledData;
foreach (DataTable tab in dataArray[0].Tables)
{
foreach (DataRow row in tab.Rows)
{
for (int i = 0; i < tab.Columns.Count; i++)
{
Console.WriteLine(row[i]);
}
}
}
Console.WriteLine("*************************************************");
Console.WriteLine("\nHit <RETURN> to stop polling");
}
}
class PollingCredentials : 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 PollingCredentials();
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
{
Console.WriteLine("Sample started...");
Console.WriteLine("Press any key to start polling...");
Console.ReadLine();
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";
Console.WriteLine("Binding properties assigned...");
// 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") };
PollingCredentials credentials = new PollingCredentials();
credentials.UserName.UserName = "<Enter user name here>";
credentials.UserName.Password = "<Enter password here>";
Console.WriteLine("Opening service host...");
PollingService service = new PollingService();
serviceHost = new ServiceHost(service, baseUri);
serviceHost.Description.Behaviors.Add(credentials);
serviceHost.AddServiceEndpoint("PollingOperation", binding, ConnectionUri);
serviceHost.Open();
Console.WriteLine("Service host opened...");
Console.WriteLine("Polling started...");
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 polling
if (serviceHost.State == CommunicationState.Opened)
serviceHost.Close();
else
serviceHost.Abort();
}
}
}
}
Vedere anche
Eseguire il poll SQL Server usando l'adapter SQL con il modello di servizio WCF