Condividi tramite


Ricevere messaggi modificati sui dati basati sul polling nel database Oracle usando il modello di servizio WCF

È possibile configurare l'adapter Microsoft BizTalk per Oracle Database per ricevere i messaggi modificati dei dati basati sul polling in una tabella o una vista Oracle. Per ricevere messaggi modificati dai dati, l'adapter 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 di database Oracle 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 usando l'adapter Oracle Database, vedere Ricevere messaggi modificati dei dati basati sul polling nell'adapter Oracle Database. È consigliabile leggere questo argomento prima di procedere.

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 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).

    Gli argomenti di questa sezione forniscono informazioni e procedure utili per eseguire il polling su tabelle e visualizzazioni del 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 viene fornito con gli esempi bizTalk Adapter Pack. Per altre informazioni sugli esempi, vedere Esempi di adapter.

Configurazione del polling nel modello di servizio WCF

È possibile configurare l'adapter Oracle Database per eseguire il polling in tabelle e visualizzazioni del 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 impostare parametri di connessione e 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. Impostare il parametro di connessione quando si aggiunge un listener del servizio all'host del servizio.

    L'elenco seguente fornisce 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.

  • Proprietà di associazione AcceptCredentialsInUri . È necessario impostare questa proprietà di associazione su true durante l'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.

  • Parametro della stringa di query PollingId nell'URI di connessione. Se si vuole 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 modificati dei dati basati sul polling nell'adapter Oracle Database.

Contratto e classe del servizio WCF

È possibile usare il plug-in Add Adapter Service Reference Visual Studio o 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 associazione PollingStatement . L'adapter 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 lo spazio dei nomi 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 messaggio

Lo spazio dei nomi del contratto del 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 del contratto dati

Un contratto dati è un accordo formale tra un servizio e un client che descrive astrattamente i dati da scambiare. Vale a dire, 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 dati viene modificato anche 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 usato 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 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 questa classe autonomamente. Il codice seguente mostra la classe di 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 dall'adapter Oracle Database

  1. Usare il plug-in Add Adapter Service Reference o svcutil.exe per generare un contratto di servizio WCF (interfaccia) e classi helper 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. Almeno, è necessario impostare la proprietà di associazione PollingStatement quando ci si connette all'adapter. Facoltativamente, è possibile specificare un parametro PollingId nell'URI di connessione. Se si usa il plug-in Aggiungi plug-in del servizio adapter, è necessario impostare tutti i parametri di associazione necessari per la configurazione. Ciò garantisce che siano impostate 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 specificare la classe di servizio WCF come indicato di seguito:

    [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 di 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 oracleDBBinding e configurare l'operazione di polling impostandone le proprietà di associazione. È possibile eseguire questa operazione in modo esplicito nel codice o in modo dichiarativo nella configurazione. Almeno, è necessario specificare l'istruzione 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 eseguire questa operazione:

    • Usare l'associazione creata nel passaggio 5.

    • Specificare un URI di connessione contenente 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'adapter 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'adapter continuerà a eseguire il polling fino alla chiusura dell'host del 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. Lo spazio dei nomi 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 mediante 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 di database Oracle usando il modello di servizio WCF