Condividi tramite


Ricevere messaggi di modifica dei dati basati sul polling nel database Oracle usando il modello di servizio WCF

È possibile configurare l'adapter Microsoft BizTalk per Oracle Database per ricevere messaggi di modifica dei dati basati sul polling su una tabella o una vista Oracle. Per ricevere messaggi di modifica dei dati, l'adattatore esegue periodicamente una query SQL su una tabella o una vista Oracle, seguita da un blocco di codice PL/SQL facoltativo. I risultati della query SQL vengono quindi restituiti dall'adapter Oracle Database all'applicazione come set di risultati fortemente tipizzato in un'operazione POLLINGSTMT in ingresso. Per altre informazioni sul meccanismo usato per configurare ed eseguire il polling in un database Oracle tramite l'adapter Oracle Database, vedere Ricevere messaggi di modifica dei dati basati sul polling nell'adapter Oracle Database. Prima di procedere, è consigliabile leggere questo argomento.

Per ricevere l'operazione POLLINGSTMT quando si usa il modello di servizio WCF, è necessario:

  • Generare un contratto di servizio WCF (interfaccia) per l'operazione POLLINGSTMT dai metadati esposti dall'adapter. A tale scopo, usare il plug-in Add Adapter Service Reference di Visual Studio o serviceModel Metadata Utility Tool (svcutil.exe).

  • Implementare un servizio WCF da questa interfaccia.

  • Ospitare questo servizio WCF usando un host del servizio (System.ServiceModel.ServiceHost).

    Negli argomenti di questa sezione vengono fornite informazioni e procedure che consentono di eseguire il polling su tabelle e viste di database Oracle nel modello di servizio WCF.

Informazioni sugli esempi usati in questo argomento

Gli esempi in questo argomento usano la tabella /SCOTT/ACCOUNTACTIVITY e la funzione /SCOTT/Package/ACCOUNT_PKG/PROCESS_ACTIVITY. Uno script per generare questi artefatti è fornito con i campioni del BizTalk Adapter Pack. Per ulteriori informazioni sugli esempi, vedere Adapter Samples.

Configurazione del polling nel modello di servizio WCF

È possibile configurare l'adapter Oracle Database per eseguire il polling su tabelle e viste di database Oracle impostando le proprietà di associazione e una proprietà di connessione facoltativa (parametro). Alcune di queste proprietà sono obbligatorie e alcune, per avere un effetto, devono essere impostate sia in fase di progettazione che in fase di esecuzione.

  • In fase di progettazione, si impostano i parametri di connessione e le proprietà di associazione quando ci si connette al database Oracle per generare un contratto di servizio WCF.

  • In fase di esecuzione si impostano le proprietà di associazione nell'oggetto OracleDBBinding usato per creare l'host del servizio. Il parametro di connessione viene impostato quando si aggiunge un listener del servizio all'host del servizio.

    L'elenco seguente offre una breve panoramica delle proprietà di associazione e dei parametri di connessione usati per configurare il polling:

  • Proprietà di associazione PollingStatement. È necessario impostare questa proprietà di associazione sia in fase di progettazione che in fase di esecuzione.

  • Proprietà di associazione facoltative. Questi devono essere impostati solo in fase di esecuzione.

  • La proprietà di associazione AcceptCredentialsInUri. È necessario impostare questa proprietà di associazione su true durante la fase di esecuzione se si desidera abilitare le credenziali nell'URI di connessione. Il nome utente e la password devono essere presenti nell'URI di connessione quando si aggiunge un endpoint di servizio all'host del servizio.

    Attenzione

    Questo esempio o materiale sussidiario fa riferimento a informazioni riservate, ad esempio una stringa di connessione o un nome utente e una password. Non inserire mai questi valori come valori codificati nel codice e assicurati di proteggere i dati riservati utilizzando l'autenticazione più sicura disponibile. Per altre informazioni, consultare la documentazione seguente:

  • Parametro di query della stringa PollingId nell'URI di connessione. Se si desidera modificare lo spazio dei nomi dell'operazione POLLINGSTMT, è necessario impostare questa proprietà di connessione sia in fase di progettazione che in fase di esecuzione.

    Per una descrizione completa delle proprietà di associazione e dei parametri di connessione usati per configurare il polling, vedere Ricevere messaggi di modifica dei dati basati sul polling nell'adapter Oracle Database.

Contratto di servizio WCF e classe

Utilizzare il plug-in Add Adapter Service Reference di Visual Studio o il ServiceModel Metadata Utility Tool (svcutil.exe) per creare un contratto di servizio WCF (interfaccia) e le classi di supporto per l'operazione POLLINGSTMT.

Quando ci si connette al database Oracle con uno di questi strumenti per generare un contratto di servizio per l'operazione POLLINGSTMT:

  • È necessario specificare la proprietà di binding PollingStatement. L'adattatore usa l'istruzione SELECT in questa proprietà di associazione per generare i metadati corretti per il set di risultati fortemente tipizzato restituito dall'operazione POLLINGSTMT.

  • Facoltativamente, è possibile specificare un parametro PollingId nell'URI di connessione. L'adapter usa questo parametro per generare il namespace per l'operazione POLLINGSTMT.

    Negli esempi seguenti:

  • PollingStatement è impostato su "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE".

  • PollingId è impostato su "AcctActivity".

Contratto di servizio WCF (interfaccia)

Il codice seguente mostra il contratto di servizio WCF (interfaccia) generato per l'operazione POLLINGSTMT.

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
[System.ServiceModel.ServiceContractAttribute(Namespace="http://Microsoft.LobServices.OracleDB/2007/03", ConfigurationName="POLLINGSTMT_OperationGroup")]  
public interface POLLINGSTMT_OperationGroup {  
  
    // CODEGEN: Generating message contract since the wrapper namespace (http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity)  
    // of message POLLINGSTMT does not match the default value (http://Microsoft.LobServices.OracleDB/2007/03)  
    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMT")]  
    void POLLINGSTMT(POLLINGSTMT request);  
}  

Contratti di messaggio

Lo spazio dei nomi del contratto di messaggio viene modificato dal parametro PollingId nell'URI di connessione. Il messaggio di richiesta restituisce un set di record fortemente tipizzato.

[System.Diagnostics.DebuggerStepThroughAttribute()]  
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
[System.ServiceModel.MessageContractAttribute(WrapperName="POLLINGSTMT", WrapperNamespace="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity", IsWrapped=true)]  
public partial class POLLINGSTMT {  
  
    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity", Order=0)]  
    public microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity.POLLINGSTMTRECORD[] POLLINGSTMTRECORD;  
  
    public POLLINGSTMT() {  
    }  
  
    public POLLINGSTMT(microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity.POLLINGSTMTRECORD[] POLLINGSTMTRECORD) {  
        this.POLLINGSTMTRECORD = POLLINGSTMTRECORD;  
    }  
}  

Spazio dei nomi per contratti dati

Un contratto dati è un accordo formale tra un servizio e un client che descrive astrattamente i dati da scambiare. Ovvero, per comunicare, il client e il servizio non devono condividere gli stessi tipi, solo gli stessi contratti dati.

In caso di messaggi di modifica dei dati, lo spazio dei nomi del contratto di dati è modificato dal parametro PollingId (se specificato) nell'URI di connessione. Il contratto dati è costituito da una classe che rappresenta un record fortemente tipizzato nel set di risultati della query. I dettagli della definizione della classe vengono omessi in questo esempio. La classe contiene proprietà che rappresentano le colonne nel set di risultati.

Nell'esempio seguente viene utilizzato l'identificativo 'PollingId' "AcctActivity".

namespace microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity {  
    using System.Runtime.Serialization;  
  
    [System.Diagnostics.DebuggerStepThroughAttribute()]  
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]  
    [System.Runtime.Serialization.DataContractAttribute(Name="POLLINGSTMTRECORD", Namespace="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity")]  
    public partial class POLLINGSTMTRECORD : object, System.Runtime.Serialization.IExtensibleDataObject {…}  
     }  
}  

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 è OracleDBBindingService.cs. È possibile inserire la logica per elaborare l'operazione POLLINGSTMT direttamente in questa classe. Se si usa svcutil.exe per generare l'interfaccia del contratto di servizio, è necessario implementare manualmente questa classe. Il codice seguente illustra la classe del servizio WCF generata dal plug-in Add Adapter Service Reference.

namespace OracleDBBindingNamespace {  
  
    public class OracleDBBindingService : POLLINGSTMT_OperationGroup {  
  
        // CODEGEN: Generating message contract since the wrapper namespace (http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity)   
        // of message POLLINGSTMT does not match the default value (http://Microsoft.LobServices.OracleDB/2007/03)  
        public virtual void POLLINGSTMT(POLLINGSTMT request) {  
            throw new System.NotImplementedException("The method or operation is not implemented.");  
        }  
    }  
}  

Ricezione dell'operazione POLLINGSTMT

Per ricevere dati di polling da Oracle Database Adapter

  1. Usare il plug-in Add Adapter Service Reference o svcutil.exe per generare un contratto di servizio WCF (interfaccia) e classi di supporto per l'operazione POLLINGSTMT. Per altre informazioni, vedere Generare un client WCF o un contratto di servizio WCF per gli artefatti della soluzione Oracle Database. È necessario impostare almeno la proprietà di associazione PollingStatement quando ci si connette all'adapter. Facoltativamente, è possibile specificare un parametro PollingId nell'URI di connessione. Se si utilizza il plug-in Aggiungi riferimento al servizio adattatore, è necessario impostare tutti i parametri di associazione richiesti per la configurazione. Ciò garantisce che siano impostati correttamente nel file di configurazione generato.

  2. Implementare un servizio WCF dalle classi di interfaccia e helper generate nel passaggio 1. Il metodo POLLINGSTMT 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 POLLINGSTMT; in caso contrario, il metodo non restituisce nulla. È necessario attribuire la classe del servizio WCF come segue:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
    
    1. Se è stato usato il plug-in Add Adapter Service Reference per generare l'interfaccia, è possibile implementare la logica direttamente nel metodo POLLINGSTMT nella classe OracleDBBindingService generata. Questa classe è disponibile in OracleDBBindingService.cs. Questo codice in questa sottoclasse di esempio esegue la classe OracleDBBindingService .

      [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
      
      public class PollingStmtService : OracleDBBindingService  
      {  
          public override void POLLINGSTMT(POLLINGSTMT request)  
          {  
              Console.WriteLine("\nNew Polling Records Received");  
              Console.WriteLine("Tx Id\tAccount\tAmount\tDate\t\t\tDescription");  
              for (int i = 0; i < request.POLLINGSTMTRECORD.Length; i++)  
              {  
                  Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", request.POLLINGSTMTRECORD[i].TID,  
                                      request.POLLINGSTMTRECORD[i].ACCOUNT,  
                                      request.POLLINGSTMTRECORD[i].AMOUNT,  
                                      request.POLLINGSTMTRECORD[i].TRANSDATE,  
                                      request.POLLINGSTMTRECORD[i].DESCRIPTION);  
              }  
          }  
      }  
      
    2. Se è stato usato svcutil.exe per generare l'interfaccia, è necessario creare un servizio WCF che implementa l'interfaccia e implementare la logica nel metodo POLLINGSTMT di questa classe.

  3. Creare un'istanza del servizio WCF creata nel passaggio 2.

    // create service instance  
    PollingStmtService pollingInstance = new PollingStmtService();  
    
  4. Creare un'istanza di System.ServiceModel.ServiceHost usando il servizio WCF e un URI di connessione di base. L'URI della connessione di base non può contenere userinfoparams o un query_string.

    // Enable service host  
    Uri[] baseUri = new Uri[] { new Uri("oracledb://Adapter") };  
    ServiceHost srvHost = new ServiceHost(pollingInstance, baseUri);  
    
  5. Creare un'istanza di OracleDBBinding e configurare l'operazione di polling impostando le relative proprietà di associazione. È possibile eseguire questa operazione in modo esplicito nel codice o in modo dichiarativo nella configurazione. È necessario specificare almeno la dichiarazione di polling e l'intervallo di polling. In questo esempio si specificano le credenziali come parte dell'URI, quindi è necessario impostare anche AcceptCredentialsInUri su true.

    // Create and configure a binding for the service endpoint. NOTE: binding  
    // parameters are set here for clarity, but these are already set in the  
    // the generated configuration file  
    OracleDBBinding binding = new OracleDBBinding();  
    
    // The credentials are included in the connection URI, so set this property to true  
    binding.AcceptCredentialsInUri = true;  
    
    // Same as statement specified in Configure Adapter dialog box  
    binding.PollingStatement = "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE";  
    binding.PostPollStatement = "BEGIN ACCOUNT_PKG.PROCESS_ACTIVITY(); END;";  
    
    // Be sure to set the interval long enough to complete processing before  
    // the next poll  
    binding.PollingInterval = 15;  
    // Polling is transactional; be sure to set an adequate isolation level   
    // for your environment  
    binding.TransactionIsolationLevel = TransactionIsolationLevel.ReadCommitted;  
    
  6. Aggiungere un endpoint di servizio all'host del servizio. Per fare questo:

    • Usare l'associazione creata nel passaggio 5.

    • Specificare un URI di connessione che contiene le credenziali e, se necessario, un PollingId.

    • Specificare il contratto come "POLLINGSTMT_OperationGroup".

    // Add service endpoint: be sure to specify POLLINGSTMT_OperationGroup as the contract  
    Uri serviceUri = new Uri("oracledb://User=SCOTT;Password=TIGER@Adapter?PollingId=AcctActivity");  
    srvHost.AddServiceEndpoint("POLLINGSTMT_OperationGroup", binding, serviceUri);  
    
  7. 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  
    srvHost.Open();  
    
  8. Per terminare il polling, chiudere l'host del servizio.

    Importante

    L'adattatore continuerà a eseguire il polling fino alla chiusura dell'host di servizio.

    srvHost.Close();  
    

Esempio

Nell'esempio seguente viene illustrata una query di polling eseguita sulla tabella /SCOTT/ACCOUNTACTIVITY. L'istruzione post-poll richiama una funzione Oracle che sposta i record elaborati in un'altra tabella /SCOTT/ACCOUNTHISTORY. Il namespace dell'operazione POLLINGSTMT viene modificato impostando il parametro PollingId su "AccountActivity" nell'URI di connessione. In questo esempio il servizio WCF per l'operazione POLLINGSTMT viene creato tramite la sottoclasse della classe OracleDBBindingService generata; Tuttavia, è possibile implementare la logica direttamente nella classe generata.

using System;  
using System.Collections.Generic;  
using System.Text;  
  
// Add these three references to use the Oracle adapter  
using System.ServiceModel;  
using Microsoft.ServiceModel.Channels;  
using Microsoft.Adapters.OracleDB;  
  
using microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity;  
using OracleDBBindingNamespace;  
  
namespace OraclePollingSM  
{  
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
  
    public class PollingStmtService : OracleDBBindingService  
    {  
        public override void POLLINGSTMT(POLLINGSTMT request)  
        {  
            Console.WriteLine("\nNew Polling Records Received");  
            Console.WriteLine("Tx Id\tAccount\tAmount\tDate\t\t\tDescription");  
            for (int i = 0; i < request.POLLINGSTMTRECORD.Length; i++)  
            {  
                Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", request.POLLINGSTMTRECORD[i].TID,  
                                    request.POLLINGSTMTRECORD[i].ACCOUNT,  
                                    request.POLLINGSTMTRECORD[i].AMOUNT,  
                                    request.POLLINGSTMTRECORD[i].TRANSDATE,  
                                    request.POLLINGSTMTRECORD[i].DESCRIPTION);  
  
            }  
            Console.WriteLine("\nHit <RETURN> to stop polling");  
         }  
    }  
  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            ServiceHost srvHost = null;  
  
            // This URI is used to specify the address for the ServiceEndpoint  
            // It must contain credentials and the PollingId (if any) that was used to generate  
            // the WCF service callback interface  
            Uri serviceUri = new Uri("OracleDb://User=SCOTT;Password=TIGER@Adapter?PollingId=AcctActivity");  
  
            // This URI is used to initialize the ServiceHost. It cannot contain  
            // userinfoparms (credentials) or a query_string (PollingId); otherwise,  
            // an exception is thrown when the ServiceHost is initialized.  
            Uri[] baseUri = new Uri[] { new Uri("OracleDb://Adapter") };  
  
            Console.WriteLine("Sample started, initializing service host -- please wait");  
  
            // create an instanc of the WCF service callback class  
            PollingStmtService pollingInstance = new PollingStmtService();  
  
            try  
            {  
                // Create a ServiceHost with the service callback instance and a base URI (address)  
                srvHost = new ServiceHost(pollingInstance, baseUri);  
  
                // Create and configure a binding for the service endpoint. Note: binding  
                // parameters are set here for clarity but these are already set in the  
                // generated configuration file  
                //  
                // The following properties are set  
                //    AcceptCredentialsInUri (true) to enable credentials in the connection URI for AddServiceEndpoint  
                //    PollingStatement  
                //    PostPollStatement calls PROCESS_ACTIVITY on Oracle. This procedure moves the queried records to  
                //                      the ACCOUNTHISTORY table  
                //    PollingInterval (15 seconds)  
                //    TransactionIsolationLevel   
  
                OracleDBBinding binding = new OracleDBBinding();  
  
                // The Credentials are included in the Connection Uri so set this property true  
                binding.AcceptCredentialsInUri = true;  
  
                // Same as statement specified in Configure Adapter dialog box  
                binding.InboundOperationType = InboundOperation.Polling;  
                binding.PollingStatement = "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE";  
                binding.PostPollStatement = "BEGIN ACCOUNT_PKG.PROCESS_ACTIVITY(); END;";  
  
                // Be sure to set the interval long enough to complete processing before  
                // the next poll  
                binding.PollingInterval = 15;  
  
                // Polling is transactional, be sure to set an adequate isolation level   
                // for your environment  
                binding.TransactionIsolationLevel = TransactionIsolationLevel.ReadCommitted;  
  
                // Add service endpoint: be sure to specify POLLINGSTMT_OperationGroup as the contract  
                srvHost.AddServiceEndpoint("POLLINGSTMT_OperationGroup", binding, serviceUri);  
  
                Console.WriteLine("Opening the service host");  
                // Open the service host to begin polling  
                srvHost.Open();  
  
                // Wait to receive request  
                Console.WriteLine("\nPolling started. Returned records will be written to the console.");  
                Console.WriteLine("Hit <RETURN> to stop polling");  
                Console.ReadLine();  
            }  
            catch (Exception e)  
            {  
                Console.WriteLine("Exception :" + e.Message);  
                Console.ReadLine();  
  
                /* If there is an Oracle 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 (srvHost.State == CommunicationState.Opened)  
                    srvHost.Close();  
                else  
                    srvHost.Abort();  
            }  
  
        }  
    }  
}  

Vedere anche

Sviluppare applicazioni Oracle Database usando il modello di servizio WCF