Streaming von Oracle Database LOB-Datentypen mithilfe des WCF-Kanalmodells
Der Microsoft BizTalk-Adapter für Oracle-Datenbank unterstützt das End-to-End-Streaming von LOB-Daten für bestimmte Vorgänge. In den Abschnitten in diesem Thema wird beschrieben, wie Das Streaming für LOB-Daten implementiert wird, wenn Sie das WCF-Kanalmodell verwenden.
Hintergrundinformationen dazu, wie der Adapter das Streaming von LOB-Datentypen unterstützt, finden Sie unter Streaming großer Objektdatentypen im Oracle Database-Adapter. Sie sollten dieses Thema lesen, bevor Sie fortfahren.
Ein Beispiel, das das Datenstreaming von LOB veranschaulicht, ist in den SDK-Beispielen verfügbar, die mit dem Oracle Database-Adapter enthalten sind. Weitere Informationen finden Sie unter Beispiele im SDK.
Streaming ausgehender Nachrichten an den Adapter
Der Adapter unterstützt End-to-End-LOB-Datenstreaming für die Anforderungsmeldung für den UpdateLOB-Vorgang.
Um End-to-End-Streaming bei UpdateLOB-Vorgängen im WCF-Kanalmodell zu unterstützen, müssen Sie:
Legen Sie die UseAmbientTransaction-Bindungseigenschaft auf true fest.
Implementieren Sie einen System.ServiceModel.Channels.BodyWriter , der in der Lage ist, die LOB-Daten zu streamen (Knotenwert-Streaming für die LOB-Daten).
Führen Sie den UpdateLOB-Vorgang innerhalb eines Transaktionsbereichs aus.
Erstellen Sie system.ServiceModel.Message , die zum Aufrufen des Vorgangs verwendet wird, indem Sie den Nachrichtentext mit diesem BodyWriter mithilfe einer entsprechenden Überladung der Message.Create-Methode bereitstellen.
Festlegen der UseAmbientTransaction-Bindungseigenschaft
Das folgende Beispiel zeigt, wie Sie eine Bindung für den Oracle Database-Adapter erstellen und die UseAmbientTransaction-Bindungseigenschaft festlegen.
// Create binding
OracleDBBinding odbBinding = new OracleDBBinding();
//set the binding property
binding.UseAmbientTransaction = true;
Implementieren eines BodyWriter
Das folgende Beispiel zeigt eine Implementierung eines BodyWriter-Steuerelements , das Das Streaming mit Knotenwert ausführt.
/// <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
}
Ausführen der Vorgänge innerhalb eines Transaktionsbereichs
Das folgende Beispiel zeigt, wie Vorgänge innerhalb eines Transaktionsbereichs ausgeführt werden.
// Create a transaction scope
using(TransactionScope tx = new TransactionScope())
{
// perform operations within the transaction
// ...
// ...
//Complete the transaction
tx.Complete()
}
Erstellen einer Nachricht mit einem BodyWriter
Das folgende Beispiel zeigt, wie Sie eine UpdateLOB-Anforderungsnachricht mithilfe von BodyWriter im vorherigen Beispiel erstellen. Die Nachrichtendaten werden aus einer Datei gelesen.
// 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();
}
Streaming eingehender Nachrichten vom Adapter
Der Adapter unterstützt End-to-End-LOB-Datenstreaming für die folgenden eingehenden Nachrichten:
Antwortmeldung für Funktionen mit OUT- oder IN OUT-Parametern, die LOB-Daten enthalten. Beachten Sie, dass RECORD TYPE-Parameter LOB-Datenspalten enthalten können.
Antwortmeldung für Funktionen mit OUT REF CURSOR-Parametern (oder Rückgabewerten), die LOB-Daten enthalten. Dies schließt die Ausgabeseite von IN OUT REF CURSOR-Parametern ein.
Antwortmeldung für Prozeduren mit IN- oder IN OUT-Parametern, die LOB-Daten enthalten. Beachten Sie, dass RECORD TYPE-Parameter LOB-Datenspalten enthalten können.
Antwortmeldung für Prozeduren mit OUT REF CURSOR-Parametern, die LOB-Daten enthalten. Dies schließt die Ausgabeseite von IN OUT REF CURSOR-Parametern ein.
Antwortmeldung für SQLEXECUTE-Vorgänge, die Resultsets zurückgeben, die LOB-Daten enthalten.
Antwortmeldung für Tabelle oder Ansicht Auswählen von Vorgängen, die LOB-Daten im Resultset zurückgeben.
Anforderungsnachricht für den (eingehenden) POLLINGSTMT-Vorgang
Um End-to-End-Streaming für eine eingehende Nachricht im WCF-Kanalmodell zu unterstützen, müssen Sie:
Implementieren sie eine System.Xml. XmlDictionaryWriter , der in der Lage ist, die LOB-Daten zu streamen (knotenwertbasiertes Streaming für die LOB-Daten).
Nutzen Sie die Message , indem Sie die WriteBodyContents-Methode mit diesem XmlDictionaryWriter aufrufen.
Implementieren eines XmlDictionaryWriter
Das folgende Beispiel zeigt eine Implementierung eines XmlDictionaryWriter,das Knotenwertstreaming ausführt.
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; }
}
}
Verwenden einer Nachricht mit einem XmlDictionaryWriter
Das folgende Beispiel zeigt, wie eine Tabelle Select-Antwortnachricht mithilfe des im vorherigen Beispiel implementierten FileXmlWriter verwendet wird. (Die FileWriter-Klasse wurde durch Die Unterklassierung von XmlDictionaryWriter erstellt.) Im Beispiel wird ein IRequestChannel-Kanal verwendet, um den Select-Vorgang aufzurufen. Die Details der Kanalerstellung wurden nicht angegeben. Die Select-Anforderungsnachricht wird aus einer Datei gelesen, und die Select-Antwortnachricht wird in eine Datei geschrieben.
// 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();
Der folgende XML-Code zeigt die Anforderungsmeldung (Inhalt der select.xml-Datei) für den Select-Vorgang an. Die TABELLE CUSTOMER enthält eine BLOB-Spalte mit dem Namen PHOTO.
<Select xmlns="http://Microsoft.LobServices.OracleDB/2007/03/SCOTT/Table/CUSTOMER">
<COLUMN_NAMES>*</COLUMN_NAMES>
<FILTER>NAME='Kim Ralls'</FILTER>
</Select>
Weitere Informationen
Entwickeln von Oracle Database-Anwendungen mithilfe des WCF-Kanalmodells