可以使用 IRequestChannel 或 IOutputChannel 形状来调用 Oracle 数据库适配器上的操作,以将消息发送到适配器。 基本模式是使用绑定(OracleDBBinding)和从连接 URI 创建的终结点,为所需的通道形状创建通道工厂。 然后,创建一个 消息 实例,该实例表示符合目标作的消息架构的 SOAP 消息。 然后,可以使用从通道工厂创建的通道将此 消息 发送到 Oracle 数据库适配器。 如果使用 IRequestChannel,则会收到响应。 如果在 Oracle 数据库上执行作时遇到问题,Oracle 数据库适配器将引发 Microsoft.ServiceModel.Channels.Common.TargetSystemException。
有关如何在 WCF 中使用 IRequestChannel 发送操作的概述,请参阅在以下位置 https://go.microsoft.com/fwlink/?LinkId=106081的“客户端 Channel-Level 程序设计”。
本主题中的各部分提供了信息,以帮助您通过 WCF 通道模型调用 Oracle 数据库适配器上的操作。
为出站操作创建与消费消息
若要对 Oracle 数据库适配器调用操作,请使用 IRequestChannel 或 IOutputChannel 发送针对目标操作的请求消息。 如果使用 IRequestChannel ,适配器将返回响应消息中作的结果。
有关请求和响应消息架构以及每个操作的消息动作的详细信息,请参阅 适用于 Oracle 数据库的 BizTalk 适配器的消息和消息架构。
如何创建请求消息和消费响应消息会决定适配器执行的是节点流式处理还是节点值流式处理。 这反过来又决定了在对受支持的操作中是否执行 LOB 数据的端到端流处理。
创建请求消息
可以通过以下两种方式之一创建请求消息:
若要创建可用于节点值流式处理的消息,必须在实现节点值流式处理的 XmlBodyWriter 中传递消息正文。
若要创建可用于节点流式处理的消息,可以在 XmlReader 中传递消息正文。
通常使用节点值流式处理来支持请求消息中 Oracle LOB 数据的端到端流式处理。 支持此功能的唯一操作是 UpdateLOB。
消费响应消息
可以通过以下两种方式之一使用响应消息:
若要使用节点值流式处理使用消息,必须在响应消息上调用 WriteBodyContents 方法,并向其传递实现节点值流式处理的 XmlDictionaryWriter 。
若要使用节点流式处理来使用消息,可以在响应消息上调用 GetReaderAtBodyContents 以获取 XmlReader。
通常使用节点值流传输来支持响应消息中 Oracle LOB 数据的端到端流式处理。 有许多操作支持此功能。
LOB 数据和消息流式处理支持
有关 Oracle 数据库适配器如何支持对 LOB 数据进行流式处理的详细信息,请参阅 Oracle 数据库适配器中的流式处理大型对象数据类型。
有关在代码中实现节点值流式处理以支持 LOB 数据的端到端流式处理的详细信息,请参阅 使用 WCF 通道模型的流式处理 Oracle Database LOB 数据类型。
WCF 通道模型中出站操作的事务支持。
适配器在 Oracle 数据库上执行的每个操作都会在一个专用事务内进行。 可以通过设置 TransactionIsolationLevel 绑定属性来控制这些事务的隔离级别。
关于本主题中使用的示例
本主题中的示例使用 SCOTT.ACCOUNTACTIVITY 表。 SDK 示例中附带了生成这些构件的脚本。 有关 SDK 示例的详细信息,请参阅 SDK 中的示例。
如何使用通道调用操作?
若要使用 IRequestChannel 调用作,请执行以下步骤。
如何使用一个 IRequestChannel 实例执行操作
生成通道工厂(ChannelFactory<IRequestChannel>)。 为此,必须指定绑定(OracleDBBinding)和终结点地址。 可以在代码中以强制方式指定绑定和终结点地址,也可以在配置中以声明方式指定终结点地址。 有关如何在配置中指定绑定和终结点地址的详细信息,请参阅 使用 Oracle 数据库创建通道。
// 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);使用 ClientCredentials 属性设置通道工厂的用户名密码凭据。
factory.Credentials.UserName.UserName = "SCOTT"; factory.Credentials.UserName.Password = "TIGER";打开通道工厂。
factory.Open();从工厂取得一个通道并将其打开。
IRequestChannel channel = factory.CreateChannel(); channel.Open();为目标操作创建 消息 实例。 请确保为目标操作指定了消息动作。 在此示例中,通过通过文件创建 XmlReader 传递消息正文。 目标操作是 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);调用通道上的 Request 方法,将消息发送到 Oracle 数据库适配器并接收答复。 如果 Oracle 数据库遇到异常,适配器将引发 TargetSystemException。 (对于非 Oracle 异常,其他异常是可能的。可以从 TargetSystemException的 InnerException.Message 属性获取 Oracle 错误的说明。
try { Message messageOut = channel.Request(messageIn); } catch (Exception ex) { // handle exception }处理响应。 在此示例中,对响应消息调用 GetReaderAtBodyContents 以获取消息正文。
XmlReader readerOut = messageOut.GetReaderAtBodyContents();处理完响应消息后,请关闭读取器和消息。
readerOut.Close(); messageOut.Close();请在使用完通道和通道工厂后关闭它们。 关闭工厂将关闭由该工厂创建的所有通道。
channel.Close() factory.Close();按照相同的步骤使用 IOutputChannel 形状发送消息,但以下各项除外:
在步骤 1 中创建 ChannelFactory<IOutputChannel> 。
在步骤 6 中调用通道上的 Send 方法。
channel.Send(messageIn);。没有为 IOutputChannel 返回的响应消息。
示例:
以下示例演示如何使用 IRequestChannel 通道调用 Select操作。 使用 XmlReader 解析 Select 响应消息,并将返回的记录数写入控制台。
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);
}
}
}
}