Invocar operaciones en la base de datos de Oracle mediante el modelo de canal WCF
Puede invocar operaciones en el adaptador de base de datos de Oracle mediante una forma IRequestChannel o IOutputChannel para enviar mensajes al adaptador. El patrón básico consiste en crear un generador de canales para la forma de canal necesaria mediante un enlace (OracleDBBinding) y un punto de conexión creado a partir de un URI de conexión. A continuación, se crea una instancia de Message que representa un mensaje SOAP que se ajusta al esquema de mensajes para la operación de destino. A continuación, puede enviar este mensaje al adaptador de base de datos de Oracle mediante un canal creado a partir del generador de canales. Si usa un IRequestChannel, recibirá una respuesta. Si hay un problema al ejecutar la operación en la base de datos de Oracle, el adaptador de base de datos de Oracle produce una excepción Microsoft.ServiceModel.Channels.Common.TargetSystemException.
Para obtener información general sobre cómo enviar operaciones mediante IRequestChannel en WCF, vea "Client Channel-Level Programming" en https://go.microsoft.com/fwlink/?LinkId=106081.
En las secciones de este tema se proporciona información para ayudarle a invocar operaciones en el adaptador de base de datos de Oracle mediante el modelo de canal WCF.
Creación y consumo de mensajes para operaciones salientes
Para invocar una operación en el adaptador de base de datos de Oracle, envíe el mensaje de solicitud para la operación de destino mediante IRequestChannel o IOutputChannel. Si usa un IRequestChannel , el adaptador devuelve los resultados de la operación en el mensaje de respuesta.
Para obtener información más detallada sobre los esquemas de mensajes de solicitud y respuesta y las acciones de mensaje para cada operación, vea Messages and Message Schemas for BizTalk Adapter for Oracle Database.
La forma en que crea el mensaje de solicitud y consume el mensaje de respuesta determina si el adaptador realiza el streaming de nodo o el streaming de valor del nodo. Esto, a su vez, determina si el streaming de un extremo a otro de los datos loB se realiza para las operaciones admitidas.
Creación del mensaje de solicitud
Puede crear el mensaje de solicitud de una de estas dos maneras:
Para crear un mensaje que se pueda usar para el streaming de nodo-valor, debe pasar el cuerpo del mensaje en un objeto XmlBodyWriter que implemente el streaming de valores de nodo.
Para crear un mensaje que se pueda usar para el streaming de nodos, puede pasar el cuerpo del mensaje en un objeto XmlReader.
Normalmente, se usa el streaming de valor de nodo para admitir el streaming de un extremo a otro de los datos loB de Oracle en el mensaje de solicitud. La única operación que admite esta característica es UpdateLOB.
Consumo del mensaje de respuesta
Puede consumir el mensaje de respuesta de una de estas dos maneras:
Para consumir el mensaje mediante streaming de nodo-valor, debe llamar al método WriteBodyContents en el mensaje de respuesta y pasarlo un XmlDictionaryWriter que implemente streaming de valor de nodo.
Para consumir el mensaje mediante streaming de nodo, puede llamar a GetReaderAtBodyContents en el mensaje de respuesta para obtener un objeto XmlReader.
Normalmente, se usa el streaming de valor de nodo para admitir el streaming de un extremo a otro de los datos loB de Oracle en el mensaje de respuesta. Hay muchas operaciones que admiten esta característica.
Compatibilidad con datos lob y streaming de mensajes
Para obtener más información sobre cómo el adaptador de base de datos de Oracle admite el streaming en datos loB, consulte Streaming de tipos de datos de objetos grandes en el adaptador de base de datos de Oracle.
Para obtener más información sobre la implementación de streaming de valores de nodo en el código para admitir el streaming de un extremo a otro de los datos LOB, vea Streaming de tipos de datos lob de base de datos de Oracle mediante el modelo de canal WCF.
Compatibilidad con transacciones en operaciones salientes en el modelo de canal WCF.
El adaptador ejecuta cada operación que se invoca dentro de una transacción dedicada en la base de datos de Oracle. Puede controlar el nivel de aislamiento de estas transacciones estableciendo la propiedad de enlace TransactionIsolationLevel .
Acerca de los ejemplos usados en este tema
En el ejemplo de este tema se usa SCOTT. Tabla ACCOUNTACTIVITY. Se proporciona un script para generar estos artefactos con los ejemplos del SDK. Para obtener más información sobre los ejemplos del SDK, consulte Ejemplos en el SDK.
¿Cómo se invoca una operación mediante un canal?
Para invocar una operación mediante un IRequestChannel, realice los pasos siguientes.
Cómo invocar una operación mediante una instancia de IRequestChannel
Cree un generador de canales (ChannelFactory<IRequestChannel>). Para ello, debe especificar un enlace (OracleDBBinding) y una dirección de punto de conexión. Puede especificar la dirección de enlace y punto de conexión de forma imperativa en el código o mediante declaración en la configuración. Para obtener más información sobre cómo especificar el enlace y la dirección del punto de conexión en la configuración, consulte Creación de un canal mediante Oracle Database.
// Create a binding OracleDBBinding binding = new OracleDBBinding(); // Create an endpoint address by using the connection URI EndpointAddress address = new EndpointAddress("oracledb://ADAPTER"); // Create the channel factory ChannelFactory<IRequestChannel> factory = new ChannelFactory<IRequestChannel>(binding, address);
Establezca las credenciales de contraseña de nombre de usuario para el generador de canales mediante la propiedad ClientCredentials .
factory.Credentials.UserName.UserName = "SCOTT"; factory.Credentials.UserName.Password = "TIGER";
Abra el generador de canales.
factory.Open();
Obtenga un canal del generador y ábralo.
IRequestChannel channel = factory.CreateChannel(); channel.Open();
Cree una instancia de Message para la operación de destino. Asegúrese de que se especifica la acción de mensaje para la operación de destino. En este ejemplo, el cuerpo del mensaje se pasa mediante la creación de un objeto XmlReader a través de un archivo. La operación de destino es una operación Select en la tabla SCOTT/EMP.
XmlReader readerIn = XmlReader.Create("SelectAllActivity.xml"); Message messageIn = Message.CreateMessage(MessageVersion.Default, "http://Microsoft.LobServices.OracleDB/2007/03/SCOTT/Table/ACCOUNTACTIVITY/Select", readerIn);
Invoque el método Request en el canal para enviar el mensaje al adaptador de Oracle Database y recibir la respuesta. Si la base de datos de Oracle encuentra una excepción, el adaptador produce una excepción TargetSystemException. (Otras excepciones son posibles para excepciones que no son de Oracle). Puede obtener una descripción del error de Oracle de la propiedad InnerException.Message de TargetSystemException.
try { Message messageOut = channel.Request(messageIn); } catch (Exception ex) { // handle exception }
Procese la respuesta. En este ejemplo, se llama a GetReaderAtBodyContents en el mensaje de respuesta para obtener el cuerpo del mensaje.
XmlReader readerOut = messageOut.GetReaderAtBodyContents();
Cuando haya terminado de procesar el mensaje de respuesta, cierre el lector y el mensaje.
readerOut.Close(); messageOut.Close();
Cuando haya terminado de usar el canal y el generador de canales, ciérralos. Al cerrar el generador, se cerrarán todos los canales creados con él.
channel.Close() factory.Close();
Siga los mismos pasos para enviar un mensaje mediante la forma IOutputChannel , excepto:
En el paso 1 se crea un ChannelFactory<IOutputChannel> .
Llame al método Send en el canal en el paso 6.
channel.Send(messageIn);
.No se devuelve ningún mensaje de respuesta para un IOutputChannel.
Ejemplo
En el ejemplo siguiente se muestra cómo invocar una operación Select mediante un canal IRequestChannel . El mensaje de respuesta Select se consume mediante xmlReader y el número de registros devueltos se escribe en la consola.
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.ServiceModel.Channels;
using Microsoft.Adapters.OracleDB;
using System.Xml;
using System.IO;
using System.Runtime.Serialization;
namespace RequestChanneSample
{
class Program
{
static void Main(string[] args)
{
// The Select operation request message
const string selectRequestString =
"\<Select xmlns=\"http://Microsoft.LobServices.OracleDB/2007/03/SCOTT/Table/ACCOUNTACTIVITY\"\>" +
"<COLUMN_NAMES>*</COLUMN_NAMES>" +
"<FILTER>ACCOUNT = 100002</FILTER>" +
"</Select>";
try
{
// Create binding -- specify binding properties before you open the factory.
OracleDBBinding odbBinding = new OracleDBBinding();
// Create address.
EndpointAddress odbAddress = new EndpointAddress("oracledb://ADAPTER/");
// Create channel factory from binding and address.
ChannelFactory<IRequestChannel> factory =
new ChannelFactory<IRequestChannel>(odbBinding, odbAddress);
// Specify credentials
factory.Credentials.UserName.UserName = "SCOTT";
factory.Credentials.UserName.Password = "TIGER";
// Open the factory.
factory.Open();
// Get a channel.
IRequestChannel channel = factory.CreateChannel();
// Open the channel.
channel.Open();
// Create the request message from the string
StringReader strReader = new StringReader(selectRequestString);
XmlReader readerIn = XmlReader.Create(strReader);
Message requestMessage = Message.CreateMessage(MessageVersion.Default,
"http://Microsoft.LobServices.OracleDB/2007/03/SCOTT/Table/ACCOUNTACTIVITY/Select",
readerIn);
Send the message and get a respone
Message responseMessage = channel.Request(requestMessage);
// Get an XmlReader from the message
XmlReader readerOut = (XmlReader) responseMessage.GetReaderAtBodyContents();
// Count the number of records returned and write to the console.
readerOut.MoveToContent();
int numberOfRecordsReturned = 0;
while (readerOut.Read())
{
if (readerOut.NodeType == XmlNodeType.Element && readerOut.Name == "ACCOUNTACTIVITYRECORDSELECT")
numberOfRecordsReturned++;
}
Console.WriteLine("{0} records returned.", numberOfRecordsReturned);
// Close the output reader and message
readerOut.Close();
responseMessage.Close();
//Close channel
channel.Close();
//Close the factory
factory.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Consulte también
Desarrollo de aplicaciones de Oracle Database mediante el modelo de canal WCF