Ricevere messaggi fortemente tipizzato basato sui dati modificati da SQL Server tramite il modello di servizio WCF
È possibile configurare l'adapter SQL per ricevere messaggi di polling fortemente tipizzato da SQL Server. È 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. È necessario usare il polling fortemente tipizzato in uno scenario in cui si desidera ricevere un set di risultati fortemente tipizzato. Per altre informazioni su come l'adattatore supporta il polling fortemente tipizzato, 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 univoco.
Come illustra il polling in questo argomento
In questo argomento, per illustrare come l'adapter SQL supporta la ricezione di messaggi di modifica dei dati fortemente tipizzato, creare un'applicazione .NET e generare il contratto di servizio WCF per l'operazione TypedPolling . Assicurarsi di specificare quanto segue durante la generazione del contratto di servizio WCF:
È necessario specificare un Valore InboundID come parte dell'URI di connessione.
È necessario specificare un'istruzione di polling per la proprietà di associazione PollingStatement .
Inoltre, se si desidera specificare altre proprietà di associazione correlate al polling durante la generazione della classe proxy, 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 durante la generazione delle classi helper e del contratto di servizio WCF:
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 del polling tipizzato 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. Oltre alla proprietà di associazione PollingStatement , tutte le altre proprietà di associazione elencate in questa sezione sono necessarie durante l'esecuzione dell'applicazione .NET. È necessario specificare la proprietà di associazione PollingStatement prima di generare l'operazione TypedPolling del contratto di servizio WCF.
Binding, proprietà | Descrizione |
---|---|
InboundOperationType | Specifica se si desidera eseguire l'operazione polling, TypedPolling o Notification in ingresso. Il valore predefinito è Polling. Per ricevere messaggi di polling fortemente tipizzato, impostarlo su TypedPolling. |
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. Importante: Per TypedPolling, è necessario specificare questa proprietà di associazione prima di generare metadati. |
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.
Configurare il polling fortemente tipizzato 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 TypedPolling dai metadati esposti dall'adattatore. A tale scopo, è possibile usare il plug-in Add Adapter Service Reference di Visual Studio. Durante la generazione del contratto di servizio WCF per questo esempio, assicurarsi di:
Specificare InboundID come Employee.
Specificare un'istruzione di polling per la proprietà di associazione PollingStatement . Per questo esempio, specificare l'istruzione di polling come:
SELECT * FROM Employee;EXEC MOVE_EMP_DATA;EXEC ADD_EMP_DETAILS John, Tester, 100000
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, TypedPolling_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 classi di supporto per l'operazione TypedPolling . 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 TypedPolling .
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://schemas.microsoft.com/Sql/2008/05/", ConfigurationName="TypedPolling_Employee")]
public interface TypedPolling_Employee {
// CODEGEN: Generating message contract since the wrapper namespace (https://schemas.microsoft.com/Sql/2008/05/TypedPolling/Employee) of message TypedPolling
// does not match the default value (https://schemas.microsoft.com/Sql/2008/05/)
[System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="TypedPolling")]
void TypedPolling(TypedPolling 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 è stato specificato l'ID in ingresso come Employee. Il messaggio di richiesta restituisce un set di risultati fortemente tipizzato.
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="TypedPolling", WrapperNamespace="http://schemas.microsoft.com/Sql/2008/05/TypedPolling/Employee", IsWrapped=true)]
public partial class TypedPolling {
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/Sql/2008/05/TypedPolling/Employee", Order=0)]
public schemas.microsoft.com.Sql._2008._05.TypedPolling.Employee.TypedPollingResultSet0[] TypedPollingResultSet0;
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://schemas.microsoft.com/Sql/2008/05/TypedPolling/Employee", Order=1)]
public schemas.microsoft.com.Sql._2008._05.TypedPolling.Employee.TypedPollingResultSet1[] TypedPollingResultSet1;
public TypedPolling() {
}
public TypedPolling(schemas.microsoft.com.Sql._2008._05.TypedPolling.Employee.TypedPollingResultSet0[] TypedPollingResultSet0, schemas.microsoft.com.Sql._2008._05.TypedPolling.Employee.TypedPollingResultSet1[] TypedPollingResultSet1) {
this.TypedPollingResultSet0 = TypedPollingResultSet0;
this.TypedPollingResultSet1 = TypedPollingResultSet1;
}
}
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 TypedPolling 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 : TypedPolling_Employee {
// CODEGEN: Generating message contract since the wrapper namespace (https://schemas.microsoft.com/Sql/2008/05/TypedPolling/Employee) of message TypedPolling
// does not match the default value (https://schemas.microsoft.com/Sql/2008/05/)
public virtual void TypedPolling(TypedPolling request) {
throw new System.NotImplementedException("The method or operation is not implemented.");
}
}
}
Ricevere messaggi in ingresso fortemente tipizzato per l'operazione di polling
Questa sezione fornisce istruzioni su come scrivere un'applicazione .NET per ricevere messaggi di polling in ingresso fortemente tipizzato tramite l'adapter SQL.
Usare il plug-in Add Adapter Service Reference per generare un contratto di servizio WCF (interfaccia) e classi helper per l'operazione TypedPolling . Assicurarsi di specificare quanto segue durante la generazione del contratto di servizio WCF per questo esempio:
È necessario specificare InboundID come Employee.
È necessario specificare un'istruzione di polling per la proprietà di associazione PollingStatement . Per questo esempio, specificare l'istruzione di polling come:
SELECT * FROM Employee;EXEC MOVE_EMP_DATA;EXEC ADD_EMP_DETAILS John, Tester, 100000
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 TypedPolling 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 TypedPolling ; 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 TypedPolling è 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 set di risultati fortemente tipizzato viene scritto nella console.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class PollingService : SqlAdapterBindingNamespace.SqlAdapterBindingService { public override void TypedPolling(TypedPolling request) { Console.WriteLine("\nNew Polling Records Received"); Console.WriteLine("*************************************************"); Console.WriteLine("Employee ID\tName\tDesignation\tSalary"); for (int i = 0; i < request.TypedPollingResultSet0.Length; i++) { Console.WriteLine("{0}\t{1}\t{2}\t{3}", request.TypedPollingResultSet0[i].Employee_ID, request.TypedPollingResultSet0[i].Name, request.TypedPollingResultSet0[i].Designation, request.TypedPollingResultSet0[i].Salary); } Console.WriteLine("*************************************************"); Console.WriteLine("\nHit <RETURN> to stop polling"); } }
Poiché l'adattatore 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 si creerà un'istanza di questa classe per passare le credenziali 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. È necessario specificare almeno InboundOperationType, PolledDataAvailableStatement e PollingStatement.
SqlAdapterBinding binding = new SqlAdapterBinding(); binding.InboundOperationType = InboundOperation.TypedPolling; 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 creato 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. È 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 "TypedPolling_Employee".
// Add service endpoint: be sure to specify TypedPolling_Employee as the contract Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?InboundID=Employee"); serviceHost.AddServiceEndpoint("TypedPolling_Employee", binding, ConnectionUri);
Per ricevere i dati di polling, aprire l'host del servizio. L'adattatore 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 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.
Il primo messaggio di polling conterrà tutti i record della tabella Employee. I messaggi di polling successivi conterranno solo l'ultimo record inserito dalla stored procedure ADD_EMP_DETAILS. L'adapter continuerà a eseguire il polling finché non si chiude 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;
namespace TypedPolling_ServiceModel
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class PollingService : SqlAdapterBindingNamespace.SqlAdapterBindingService
{
public override void TypedPolling(TypedPolling request)
{
Console.WriteLine("\nNew Polling Records Received");
Console.WriteLine("*************************************************");
Console.WriteLine("Employee ID\tName\tDesignation\tSalary");
for (int i = 0; i < request.TypedPollingResultSet0.Length; i++)
{
Console.WriteLine("{0}\t{1}\t{2}\t{3}",
request.TypedPollingResultSet0[i].Employee_ID,
request.TypedPollingResultSet0[i].Name,
request.TypedPollingResultSet0[i].Designation,
request.TypedPollingResultSet0[i].Salary);
}
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.TypedPolling;
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 that was used to generate
// the WCF service callback interface
Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?InboundId=Employee");
// This URI is used to initialize the ServiceHost. It cannot contain
// the 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("TypedPolling_Employee", 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 polling di SQL Server usando l'adapter SQL con il modello di servizio WCF