Freigeben über


Empfangen von abrufbasierten Daten geänderten Nachrichten in Oracle Database mithilfe des WCF-Dienstmodells

Sie können den Microsoft BizTalk Adapter für Oracle Database so konfigurieren, dass er Nachrichten über geänderte, abfragebasierte Daten für eine Oracle-Tabelle oder -Ansicht empfängt. Um datenänderungsmeldungen zu empfangen, führt der Adapter regelmäßig eine SQL-Abfrage für eine Oracle-Tabelle oder -Ansicht aus, gefolgt von einem optionalen PL/SQL-Codeblock. Die Ergebnisse der SQL-Abfrage werden dann vom Oracle Database-Adapter an Ihre Anwendung als streng typisierte Ergebnismenge während eines eingehenden POLLINGSTMT-Vorgangs zurückgegeben. Weitere Informationen zum Mechanismus, der zum Konfigurieren und Durchführen von Abfragen in einer Oracle-Datenbank mithilfe des Oracle Database-Adapters verwendet wird, finden Sie unter Empfangen von abrufbasierten, datenänderungsbasierten Nachrichten im Oracle Database-Adapter. Es wird dringend empfohlen, dieses Thema vor dem Fortfahren zu lesen.

Um den POLLINGSTMT-Vorgang bei Verwendung des WCF-Dienstmodells zu erhalten, müssen Sie:

  • Generieren Sie einen WCF-Dienstvertrag (Schnittstelle) für den POLLINGSTMT-Vorgang aus den metadaten, die vom Adapter verfügbar gemacht werden. Dazu verwenden Sie das Add Adapter Service Reference Visual Studio Plug-In oder das ServiceModel Metadata Utility Tool (svcutil.exe).

  • Implementieren Sie einen WCF-Dienst über diese Schnittstelle.

  • Hosten Sie diesen WCF-Dienst mithilfe eines Diensthosts (System.ServiceModel.ServiceHost).

    Die Themen in diesem Abschnitt enthalten Informationen und Verfahren, mit denen Sie Abfragen zu Oracle-Datenbanktabellen und -Ansichten im WCF-Dienstmodell durchführen können.

Informationen zu den in diesem Thema verwendeten Beispielen

In den Beispielen in diesem Thema werden die Tabelle /SCOTT/ACCOUNTACTIVITY und die Funktion /SCOTT/Package/ACCOUNT_PKG/PROCESS_ACTIVITY verwendet. Ein Skript zum Generieren dieser Artefakte wird mit den BizTalk Adapter Pack-Beispielen bereitgestellt. Weitere Informationen zu den Beispielen finden Sie unter Adapterbeispiele.

Konfigurieren der Abstimmung im WCF-Dienstmodell

Sie konfigurieren den Oracle-Datenbankadapter, um Abfragen für Oracle-Datenbanktabellen und -ansichten durchzuführen, indem Sie Bindungseigenschaften und eine optionale Verbindungseigenschaft (Parameter) festlegen. Einige dieser Eigenschaften sind obligatorisch, und einige müssen sowohl zur Entwurfszeit als auch zur Laufzeit festgelegt werden.

  • Zur Entwurfszeit legen Sie Verbindungsparameter und Bindungseigenschaften fest, wenn Sie eine Verbindung mit der Oracle-Datenbank herstellen, um einen WCF-Dienstvertrag zu generieren.

  • Zur Laufzeit legen Sie Bindungseigenschaften für das OracleDBBinding-Objekt fest, das Sie zum Erstellen des Diensthosts verwenden. Sie legen den Verbindungsparameter fest, wenn Sie dem Diensthost einen Dienstlistener hinzufügen.

    Die folgende Liste enthält eine kurze Übersicht über die Bindungseigenschaften und Verbindungsparameter, die zum Konfigurieren der Abfrage verwendet werden können.

  • Die PollingStatement-Bindungseigenschaft . Sie müssen diese Bindungseigenschaft sowohl zur Entwurfszeit als auch zur Laufzeit festlegen.

  • Optionale Bindungseigenschaften. Diese müssen nur zur Laufzeit festgelegt werden.

  • Die AcceptCredentialsInUri-Bindungseigenschaft . Sie müssen diese Bindungseigenschaft während der Laufzeit auf "true " festlegen, wenn Sie Anmeldeinformationen im Verbindungs-URI aktivieren möchten. Der Benutzername und das Kennwort müssen im Verbindungs-URI vorhanden sein, wenn Sie dem Diensthost einen Dienstendpunkt hinzufügen.

    Vorsicht

    In diesem Beispiel oder Leitfaden wird auf vertrauliche Informationen verwiesen, z. B. auf eine Verbindungszeichenfolge oder einen Benutzernamen und ein Kennwort. Codieren Sie diese Werte niemals in Ihrem Code, und stellen Sie sicher, dass Sie vertrauliche Daten mithilfe der sichersten verfügbaren Authentifizierung schützen. Weitere Informationen finden Sie in der folgenden Dokumentation:

  • Der Abfragezeichenfolgenparameter "PollingId" im Verbindungs-URI. Wenn Sie den Namespace des POLLINGSTMT-Vorgangs ändern möchten, müssen Sie diese Verbindungseigenschaft sowohl zur Entwurfszeit als auch zur Laufzeit festlegen.

    Eine vollständige Beschreibung der Bindungseigenschaften und Verbindungsparameter, die zum Konfigurieren des Abrufs verwendet werden, finden Sie unter Empfangen von abrufbasierten Daten geänderten Nachrichten im Oracle Database-Adapter.

WCF-Dienstvertrag und -Klasse

Sie verwenden entweder das Add Adapter Service Reference Visual Studio Plug-In oder das ServiceModel Metadata Utility Tool (svcutil.exe), um einen WCF-Dienstvertrag (Schnittstelle) und unterstützende Klassen für den POLLINGSTMT-Vorgang zu erstellen.

Wenn Sie eine Verbindung mit der Oracle-Datenbank mit einem dieser Tools herstellen, um einen Servicevertrag für den POLLINGSTMT-Vorgang zu generieren:

  • Sie müssen die Bindungseigenschaft "PollingStatement" angeben. Der Adapter verwendet die SELECT-Anweisung in diesen Bindungseinstellungen, um die richtigen Metadaten für die stark typierten Resultsets zu generieren, die vom POLLINGSTMT-Vorgang zurückgegeben werden.

  • Sie können optional einen PollingId-Parameter im Verbindungs-URI angeben. Der Adapter verwendet diesen Parameter, um den Namespace für den POLLINGSTMT-Vorgang zu generieren.

    In den folgenden Beispielen:

  • PollingStatement wurde auf "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE" festgelegt.

  • PollingId ist auf "AcctActivity" festgelegt.

Der WCF-Servicekontrakt (Schnittstelle)

Der folgende Code zeigt den WCF-Dienstvertrag (Schnittstelle), der für den POLLINGSTMT-Vorgang generiert wurde.

[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);  
}  

Die Nachrichtenverträge

Der Namespace des Nachrichtenvertrags wird durch den PollingId-Parameter in der Verbindungs-URI modifiziert. Die Anforderungsnachricht gibt einen Satz stark typierter Datensätze zurück.

[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;  
    }  
}  

Der Datenvertrags-Namespace

Ein neuer Datenvertrag ist eine formale Vereinbarung zwischen einem Dienst und einem Client, in dem die auszutauschenden Daten abstrakt beschrieben werden. Das heißt, um zu kommunizieren, müssen der Client und der Dienst nicht dieselben Typen, sondern nur die gleichen Datenverträge verwenden.

Im Falle von Datenänderungsmeldungen wird auch der Datenvertragsnamespace durch den PollingId-Parameter (sofern angegeben) im Verbindungs-URI geändert. Der Datenvertrag besteht aus einer Klasse, die einen stark typierten Datensatz im Abfrageergebnissatz darstellt. Die Details der Klassendefinition werden in diesem Beispiel nicht angegeben. Die Klasse enthält Eigenschaften, die die Spalten im Resultset darstellen.

Im folgenden Beispiel wird die PollingId "AcctActivity" verwendet.

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 {…}  
     }  
}  

WCF-Dienstklasse

Das Add-Adapter Service Reference Plug-In generiert auch eine Datei, die über einen Stub für die WCF-Dienstklasse verfügt, die aus dem Dienstvertrag (Schnittstelle) implementiert wurde. Der Name der Datei ist OracleDBBindingService.cs. Sie können die Logik einfügen, um den POLLINGSTMT-Vorgang direkt in diese Klasse zu verarbeiten. Wenn Sie svcutil.exe verwenden, um die Dienstvertragsschnittstelle zu generieren, müssen Sie diese Klasse selbst implementieren. Der folgende Code zeigt die WCF-Dienstklasse, die vom Add Adapter Service Reference Plug-In generiert wird.

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.");  
        }  
    }  
}  

Empfangen des POLLINGSTMT-Vorgangs

So empfangen Sie Abfragedaten vom Oracle Database-Adapter

  1. Verwenden Sie das Add Adapter Service Reference Plugin oder svcutil.exe, um einen WCF-Dienstvertrag, eine Schnittstelle und Hilfsklassen für den POLLINGSTMT-Vorgang zu generieren. Weitere Informationen finden Sie unter Generieren eines WCF-Clients oder eines WCF-Dienstvertrags für Oracle Database-Lösungsartefakte. Sie müssen mindestens die PollingStatement-Bindungseigenschaft festlegen, wenn Sie eine Verbindung mit dem Adapter herstellen. Sie können optional einen PollingId-Parameter im Verbindungs-URI angeben. Wenn Sie das Add Adapter Service Reference Plug-In verwenden, sollten Sie alle Bindungsparameter festlegen, die für Ihre Konfiguration erforderlich sind. Dadurch wird sichergestellt, dass sie in der generierten Konfigurationsdatei ordnungsgemäß festgelegt sind.

  2. Implementieren Sie einen WCF-Dienst über die Schnittstelle und Hilfsklassen, die in Schritt 1 generiert wurden. Die POLLINGSTMT-Methode dieser Klasse kann eine Ausnahme auslösen, um die Abruftransaktion abzubrechen, wenn beim Verarbeiten der daten, die vom POLLINGSTMT-Vorgang empfangen wurden, ein Fehler aufgetreten ist; andernfalls gibt die Methode nichts zurück. Sie müssen die WCF-Dienstklasse wie folgt attributen:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
    
    1. Wenn Sie das Add Adapter Service Reference Plug-In zum Generieren der Schnittstelle verwendet haben, können Sie Ihre Logik direkt in der POLLINGSTMT-Methode in der generierten OracleDBBindingService-Klasse implementieren. Diese Klasse finden Sie in OracleDBBindingService.cs. Dieser Code unterklassifiziert in diesem Beispiel die OracleDBBindingService-Klasse.

      [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. Wenn Sie svcutil.exe zum Generieren der Schnittstelle verwendet haben, müssen Sie einen WCF-Dienst erstellen, der die Schnittstelle implementiert und Ihre Logik in der POLLINGSTMT-Methode dieser Klasse implementiert.

  3. Erstellen Sie eine Instanz des WCF-Diensts, der in Schritt 2 erstellt wurde.

    // create service instance  
    PollingStmtService pollingInstance = new PollingStmtService();  
    
  4. Erstellen Sie eine Instanz von System.ServiceModel.ServiceHost mithilfe des WCF-Diensts und eines Basisverbindungs-URI. Der Basisverbindungs-URI darf keine Userinfoparams oder eine query_string enthalten.

    // Enable service host  
    Uri[] baseUri = new Uri[] { new Uri("oracledb://Adapter") };  
    ServiceHost srvHost = new ServiceHost(pollingInstance, baseUri);  
    
  5. Erstellen Sie ein OracleDBBinding , und konfigurieren Sie den Abrufvorgang, indem Sie die Bindungseigenschaften festlegen. Sie können dies entweder explizit im Code oder deklarativ in der Konfiguration tun. Sie müssen mindestens die Abfrageanweisung und das Abrufintervall angeben. In diesem Beispiel geben Sie die Anmeldeinformationen als Teil des URI an, damit Sie auch " AcceptCredentialsInUri " auf "true" festlegen müssen.

    // 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. Fügen Sie dem Diensthost einen Dienstendpunkt hinzu. Um dies zu tun:

    • Verwenden Sie die in Schritt 5 erstellte Bindung.

    • Geben Sie einen Verbindungs-URI an, der Anmeldeinformationen und ggf. eine PollingId enthält.

    • Geben Sie den Vertrag als "POLLINGSTMT_OperationGroup" an.

    // 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. Um Umfragedaten zu empfangen, öffnen Sie den Service-Host. Der Adapter gibt Daten zurück, wenn die Abfrage ein Resultset zurückgibt.

    // Open the service host to begin polling  
    srvHost.Open();  
    
  8. Schließen Sie den Diensthost, um die Abfrage zu beenden.

    Von Bedeutung

    Der Adapter fragt weiterhin ab, bis der Diensthost geschlossen ist.

    srvHost.Close();  
    

Beispiel

Das folgende Beispiel zeigt eine Polling-Abfrage, die gegen die Tabelle "/SCOTT/ACCOUNTACTIVITY" ausgeführt wird. Die Post-Poll-Anweisung ruft eine Oracle-Funktion auf, die die verarbeiteten Datensätze in eine andere Tabelle /SCOTT/ACCOUNTHISTORY verschiebt. Der Namespace des POLLINGSTMT-Vorgangs wird geändert, indem der PollingId-Parameter auf "AccountActivity" im Verbindungs-URI festgelegt wird. In diesem Beispiel wird der WCF-Dienst für den POLLINGSTMT-Vorgang durch Unterklassen der generierten OracleDBBindingService-Klasse erstellt. Sie können ihre Logik jedoch direkt in der generierten Klasse implementieren.

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();  
            }  
  
        }  
    }  
}  

Siehe auch

Entwickeln von Oracle-Datenbankanwendungen mithilfe des WCF-Dienstmodells