Partager via


Streaming des types de données métier Oracle Database à l’aide du modèle de canal WCF

L’adaptateur Microsoft BizTalk pour Oracle Database prend en charge la diffusion en continu de bout en bout des données métier pour certaines opérations. Les sections de cette rubrique décrivent comment implémenter la diffusion en continu pour les données métier lorsque vous utilisez le modèle de canal WCF.

Pour obtenir des informations générales sur la façon dont l’adaptateur prend en charge la diffusion en continu des types de données métier, consultez Diffusion en continu des types de données d’objet volumineux dans l’adaptateur Oracle Database. Vous devez lire cette rubrique avant de continuer.

Un exemple illustrant la diffusion en continu de données métier est disponible dans les exemples de SDK inclus avec l’adaptateur Oracle Database. Pour plus d’informations, consultez Exemples dans le Kit de développement logiciel (SDK).

Diffusion en continu de messages sortants vers l’adaptateur

L’adaptateur prend en charge le streaming de données métier de bout en bout pour le message de demande pour l’opération UpdateLOB.

Pour prendre en charge la diffusion en continu de bout en bout sur les opérations UpdateLOB dans le modèle de canal WCF, vous devez :

  1. Définissez la propriété de liaison UseAmbientTransaction sur true.

  2. Implémentez un System.ServiceModel.Channels.BodyWriter capable de diffuser en continu les données métier (en effectuant une diffusion en continu de valeur de nœud sur les données métier).

  3. Effectuez l’opération UpdateLOB dans une étendue de transaction.

  4. Créez le System.ServiceModel.Message utilisé pour appeler l’opération en fournissant le corps du message avec ce BodyWriter à l’aide d’une surcharge appropriée de la méthode Message.Create .

Définition de la propriété de liaison UseAmbientTransaction

L’exemple suivant montre comment créer une liaison pour l’adaptateur Oracle Database et définir la propriété de liaison UseAmbientTransaction .

// Create binding  
OracleDBBinding odbBinding = new OracleDBBinding();  
  
//set the binding property  
binding.UseAmbientTransaction = true;  
  

Implémentation d’un BodyWriter

L’exemple suivant montre une implémentation d’un BodyWriter qui effectue une diffusion en continu de valeur de nœud.

/// <summary>  
/// This class overrides the OnWriteBodyContents function to do node-value streaming  
/// </summary>  
class StreamingBodyWriter : BodyWriter, IDisposable  
{  
    XmlReader m_reader = null;  
  
    int m_chunkSize;  
    /// <summary>  
    /// Initializes the body writer  
    /// </summary>  
    /// <param name="reader">Reader for input</param>  
    /// <param name="chunkSize">The chunksize in which the data is passed to adapter</param>  
    public StreamingBodyWriter(XmlReader reader, int chunkSize)  
        : base(false)  
    {  
        m_reader = reader;  
        if (chunkSize \<= 0)  
            throw new ApplicationException("ChunkSize should be a positive value");  
        m_chunkSize = chunkSize;  
    }  
  
    protected override void OnWriteBodyContents(XmlDictionaryWriter writer)  
    {  
        if (m_reader == null)  
            throw new ApplicationException("Reader cannot be null");  
  
        while (m_reader.Read())  
        {  
            switch (m_reader.NodeType)  
            {  
                case XmlNodeType.Element:  
                    writer.WriteStartElement(m_reader.LocalName, m_reader.NamespaceURI);  
                    break;  
                case XmlNodeType.Text:  
                    #region Streaming Code  
                    char[] tempBuffer = new char[m_chunkSize];  
                    int length = 0;  
                    while ((length = m_reader.ReadValueChunk(tempBuffer, 0, m_chunkSize)) > 0)  
                    {  
                        writer.WriteString(new String(tempBuffer, 0, length));  
                    }  
                    #endregion  
                    break;  
                case XmlNodeType.EndElement:  
                    writer.WriteEndElement();  
                    break;  
            }  
        }  
  
    }  
  
    #region IDisposable Members  
  
    public void Dispose()  
    {  
        if (m_reader != null)  
        {  
            m_reader.Close();  
            m_reader = null;  
        }  
    }  
  
    #endregion  
}  

Effectuer les opérations dans une étendue de transaction

L’exemple suivant montre comment effectuer des opérations dans une étendue de transaction.

// Create a transaction scope  
using(TransactionScope tx = new TransactionScope())  
{  
  // perform operations within the transaction  
  // ...  
  // ...  
  
  //Complete the transaction  
  tx.Complete()  
}  
  

Création d’un message à l’aide d’un BodyWriter

L’exemple suivant montre comment créer un message de requête UpdateLOB à l’aide de BodyWriter dans l’exemple précédent. Les données de message sont lues à partir d’un fichier.

// Create a transaction scope  
using(TransactionScope tx = new TransactionScope())  
{  
    XmlReader readerIn = XmlReader.Create ("updatelob.xml");  
    // StreamingBodyWrtier class is responsible for streaming  
    StreamingBodyWriter stBW = new StreamingBodyWriter(readerIn, chunkSize);  
  
    Message InputMsg = Message.CreateMessage(MessageVersion.Default,  
    "http://Microsoft.LobServices.OracleDB/2007/03/SCOTT/Table/CUSTOMER/UpdateLOB",   
    stBW);  
  
    //Send the request message and get the output message  
    OutputMsg = channel.Request(InputMsg);  
  
    tx.Complete();  
}  
  

Diffusion en continu de messages entrants à partir de l’adaptateur

L’adaptateur prend en charge le streaming de données métier de bout en bout pour les messages entrants suivants :

  • Message de réponse pour les fonctions avec des paramètres OUT ou IN OUT qui contiennent des données métier. Notez que les paramètres RECORD TYPE peuvent contenir des colonnes de données métier.

  • Message de réponse pour les fonctions avec des paramètres OUT REF CURSOR (ou des valeurs de retour) qui contiennent des données métier. Cela inclut le côté sortie des paramètres IN OUT REF CURSOR.

  • Message de réponse pour les procédures avec des paramètres IN ou IN OUT qui contiennent des données métier. Notez que les paramètres RECORD TYPE peuvent contenir des colonnes de données métier.

  • Message de réponse pour les procédures avec des paramètres OUT REF CURSOR qui contiennent des données métier. Cela inclut le côté sortie des paramètres IN OUT REF CURSOR

  • Message de réponse pour les opérations SQLEXECUTE qui retournent des jeux de résultats qui contiennent des données métier.

  • Message de réponse pour la table ou la vue Opérations de sélection qui retournent des données métier dans le jeu de résultats.

  • Message de demande pour l’opération POLLINGSTMT (entrante)

    Pour prendre en charge la diffusion en continu de bout en bout sur un message entrant dans le modèle de canal WCF, vous devez :

  1. Implémentez un System.Xml. XmlDictionaryWriter capable de diffuser en continu les données métier (exécution d’une diffusion en continu de valeur de nœud sur les données métier).

  2. Consommez le Message en appelant la méthode WriteBodyContents avec ce XmlDictionaryWriter.

Implémentation d’un XmlDictionaryWriter

L’exemple suivant montre une implémentation d’un XmlDictionaryWriter qui effectue une diffusion en continu de valeur de nœud.

using System;  
using System.Xml;  
using System.Text;  
  
class FileXmlWriter : XmlDictionaryWriter  
{  
    XmlTextWriter xts;  
  
    public FileXmlWriter(string file)  
    {  
        xts = new XmlTextWriter(file, Encoding.UTF8);  
    }  
  
    public override void WriteBase64(byte[] buffer, int index, int count)  
    {  
        xts.WriteBase64(buffer, index, count);  
    }  
  
    public override void WriteCData(string text)  
    {  
        xts.WriteCData(text);  
    }  
  
    public override void WriteCharEntity(char ch)  
    {  
        xts.WriteCharEntity(ch);  
    }  
  
    public override void WriteChars(char[] buffer, int index, int count)  
    {  
        xts.WriteChars(buffer, index, count);  
    }  
  
    public override void WriteComment(string text)  
    {  
        xts.WriteComment(text);  
    }  
  
    public override void WriteDocType(string name, string pubid, string sysid, string subset)  
    {  
        xts.WriteDocType(name, pubid, sysid, subset);  
    }  
  
    public override void WriteEndAttribute()  
    {  
        xts.WriteEndAttribute();  
    }  
  
    public override void WriteEndDocument()  
    {  
        xts.WriteEndDocument();  
    }  
  
    public override void WriteEndElement()  
    {  
        xts.WriteEndElement();  
    }  
  
    public override void WriteEntityRef(string name)  
    {  
        xts.WriteEntityRef(name);  
    }  
  
    public override void WriteFullEndElement()  
    {  
        xts.WriteFullEndElement();  
    }  
  
    public override void WriteProcessingInstruction(string name, string text)  
    {  
        xts.WriteProcessingInstruction(name, text);  
    }  
  
    public override void WriteRaw(string data)  
    {  
        xts.WriteRaw(data);  
    }  
  
    public override void WriteRaw(char[] buffer, int index, int count)  
    {  
        xts.WriteRaw(buffer, index, count);  
    }  
  
    public override void WriteStartAttribute(string prefix, string localName, string ns)  
    {  
        xts.WriteStartAttribute(prefix, localName, ns);  
    }  
  
    public override void WriteStartDocument(bool standalone)  
    {  
        xts.WriteStartDocument(standalone);  
    }  
  
    public override void WriteStartDocument()  
    {  
        xts.WriteStartDocument();  
    }  
  
    public override void WriteStartElement(string prefix, string localName, string ns)  
    {  
        xts.WriteStartElement(localName);  
    }  
  
    public override void WriteString(string text)  
    {  
        xts.WriteString(text);  
    }  
  
    public override void WriteSurrogateCharEntity(char lowChar, char highChar)  
    {  
        xts.WriteSurrogateCharEntity(lowChar, highChar);  
    }  
  
    public override void WriteWhitespace(string ws)  
    {  
        xts.WriteWhitespace(ws);  
    }  
  
    public override void Close()  
    {  
        xts.Close();  
    }  
  
    public override void Flush()  
    {  
        xts.Flush();  
    }  
  
    public override string LookupPrefix(string ns)  
    {  
        return xts.LookupPrefix(ns);  
    }  
  
    public override WriteState WriteState  
    {  
        get { return xts.WriteState; }  
    }  
  
}  

Consommation d’un message à l’aide d’un xmlDictionaryWriter

L’exemple suivant montre comment utiliser un message de réponse sélectionner une table à l’aide de FileXmlWriter implémenté dans l’exemple précédent. (La classe FileWriter a été créée en sous-classant XmlDictionaryWriter.) L’exemple utilise un canal IRequestChannel pour appeler l’opération Select. Les détails de la création du canal ont été omis. Le message Sélectionner une demande est lu à partir d’un fichier et le message de réponse Sélectionner est écrit dans un fichier.

// Read Select message body from a file  
XmlReader readerIn = XmlReader.Create("select.xml");  
Message InputMsg = Message.CreateMessage(MessageVersion.Default,  
    "http://Microsoft.LobServices.OracleDB/2007/03/SCOTT/Table/CUSTOMER/Select", readerIn);  
  
Message OutputMsg = channel.Request(InputMsg);  
  
// Streaming response message to select_output.xml using the custom XmlDictionaryWriter;  
FileXmlWriter fileXmlWriter = new FileXmlWriter("select_output.xml");  
OutputMsg.WriteBodyContents(fileXmlWriter);  
fileXmlWriter.Flush();  
fileXmlWriter.Close();  
  
// Streaming complete close output message;  
OutputMsg.Close();  

Le code XML suivant montre le message de demande (contenu du fichier select.xml) pour l’opération Select. La table CUSTOMER contient une colonne BLOB nommée PHOTO.

<Select xmlns="http://Microsoft.LobServices.OracleDB/2007/03/SCOTT/Table/CUSTOMER">  
  <COLUMN_NAMES>*</COLUMN_NAMES>  
  <FILTER>NAME='Kim Ralls'</FILTER>  
</Select>  

Voir aussi

Développer des applications Oracle Database à l’aide du modèle de canal WCF