使用 WCF 服务模型在 Oracle 数据库中对具有大型数据类型的表完成操作。

本部分包含有关如何从 WCF 服务模型调用 ReadLOB 和 UpdateLOB 操作的信息。 对于包含 LOB 列的表和视图,将提供 ReadLOB 和 UpdateLOB 操作,即用于存储 Oracle 大型对象(LOB)数据的列。 有关 Microsoft BizTalk 适配器在 Oracle 数据库中支持的 Oracle LOB 数据类型以及 ReadLOB 和 UpdateLOB 操作的概述,请参阅 在包含 Oracle 数据库中 LOB 数据的表和视图上的操作

重要

LOB 数据列可以包含大量数据(最多 4 GB)。 使用 WCF 客户端对 LOB 列进行操作的一个重要限制是,WCF 服务模型仅支持在 ReadLOB 操作上流式传输数据,而不支持在 UpdateLOB 操作上流式传输。 这是因为 WCF 要求从服务模型进行流式处理,流式处理的参数必须是其方向的唯一参数。 UpdateLOB操作除了 LOB 数据外,还有另外两个 IN 参数(列名和行筛选器),因此在 WCF 服务模型中不支持流式处理。 因此,如果要使用大量数据更新 LOB 列,则可能需要使用 WCF 通道模型。 有关如何使用 WCF 通道模型通过 UpdateLOB 作流式传输 LOB 数据的详细信息,请参阅 使用 WCF 通道模型流式处理 Oracle LOB 数据类型

关于本主题中使用的示例

本主题中的示例使用 /SCOTT/CUSTOMER 表。 此表包含名为 PHOTO 的 BLOB 列。SDK 示例提供了用于生成此表的脚本。 有关 SDK 示例的详细信息,请参阅 SDK 中的示例

WCF 客户端类

以下示例演示为 /SCOTT/CUSTOMER 表上的 ReadLOB 操作和 UpdateLOB 操作生成的 WCF 客户端类的方法签名。

public partial class SCOTTTableCUSTOMERClient : System.ServiceModel.ClientBase<SCOTTTableCUSTOMER>,   
                                                SCOTTTableCUSTOMER   
{  
    public System.IO.Stream ReadLOB(string LOB_COLUMN, string FILTER);   
  
    public void UpdateLOB(string LOB_COLUMN, string FILTER, byte[] Stream);  
}  

注释

请注意,ReadLOB 返回数据流,但 UpdateLOB 不操作流。

调用 ReadLOB 和 UpdateLOB 作业

ReadLOBUpdateLOB 方法只能对单一数据库行中的单个 LOB 列进行作。 设置以下参数以标识目标列/行。

参数 定义
LOB_COLUMN FILTER 参数标识的行中目标列的名称;例如,“PHOTO”。
过滤器 指定目标行的 SQL SELECT 语句中 WHERE 子句的内容;例如,“NAME='Kim Ralls'”。 筛选器必须仅指定一行。 如果筛选器匹配多个行:

- ReadLOB 返回第一个匹配行的 LOB 数据。
- UpdateLOB 会引发异常。

注释

ReadLOB 返回的流不支持 Seek。 这意味着不支持 Length 等属性。

谨慎

UpdateLOB操作必须在事务范围内执行。 此外,在执行 UpdateLOB作之前,UseAmbientTransaction 绑定属性必须设置为 true

以下代码演示如何使用 WCF 客户端从文件更新 /SCOTT/CUSTOMER 表中的 BLOB PHOTO 列,并将新列数据读回文件。 可以在 SDK 示例中找到完整的示例。 有关 SDK 示例的详细信息,请参阅 SDK 中的示例

using System;  
using System.Collections.Generic;  
using System.Text;  
using System.Transaction;  
  
// Include for file streaming  
using System.IO;  
  
// Add WCF, WCF LOB Adapter SDK, and Oracle Database adapter namepaces  
using System.ServiceModel;  
using Microsoft.ServiceModel.Channels;  
using Microsoft.Adapters.OracleDB;  
  
// Include this namespace for the WCF channel model  
using System.ServiceModel.Channels;  
  
// Include this namespace for the WCF LOB Adapter SDK and Oracle Database adapter exceptions  
using Microsoft.ServiceModel.Channels.Common;  
  
using CustomerTablens = microsoft.lobservices.oracledb._2007._03;  
  
namespace OracleLobOpsSnippetSM  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            try  
            {  
                OracleDBBinding binding = new OracleDBBinding();  
                binding.UseAmbientTransaction = true; //set this to true for UpdateLOB operation  
  
                EndpointAddress endpointAddress = new EndpointAddress("oracleDB://ADAPTER");  
  
                using (SCOTTTableCUSTOMERClient customerTableClient =  
                    new SCOTTTableCUSTOMERClient(binding, endpointAddress))  
                {  
                    customerTableClient.ClientCredentials.UserName.UserName = "SCOTT";  
                    customerTableClient.ClientCredentials.UserName.Password = "TIGER";  
  
                    // Open the client to read the LOB data back  
                    customerTableClient.Open();  
  
                    // Add a photo to the customer record    
                    using (FileStream fs = new FileStream("SamplePhoto.jpg", FileMode.Open))  
                    {  
                        Console.WriteLine("Updating photo");  
                        int count = 0;  
                        byte[] photo = new byte[fs.Length];  
                        while ((count += fs.Read(photo, count, (int) (((fs.Length-count)>4096)? 4096:fs.Length-count))) \< fs.Length) ;  
  
                        // UpdateLOB operation must be performed within a transaction scope  
                        using(TransactionScope tx = new TransactionScope())  
                        {  
                           customerTableClient.UpdateLOB("PHOTO", "NAME='Kim Ralls'", photo);  
                           Console.WriteLine("Photo updated");  
                           tx.Complete();  
                        }  
                    }  
  
                    // Read the data back and store it to another file  
                    using (FileStream fs = new FileStream("PhotoCopy.jpg", FileMode.Create))  
                    {  
                        Console.WriteLine("Reading photo data");  
                        Stream photoStream = customerTableClient.ReadLOB("PHOTO", "NAME='Kim Ralls'");  
                        Console.WriteLine("Photo data read -- writing to PhotoCopy.jpg");  
  
                        int count;  
                        int length = 0;  
                        byte[] buffer = new byte[4096];  
                        while ((count = photoStream.Read(buffer, 0, 4096)) > 0)  
                        {  
                            fs.Write(buffer, 0, count);  
                            length+=count;  
                        }  
                        Console.WriteLine("{0} bytes written to PhotoCopy.jpg", length);  
                    }  
  
                }  
  
                Console.WriteLine("Photo updated and read back -- Hit <RETURN> to end");  
                Console.ReadLine();  
  
            }  
            catch (Exception ex)  
            {  
                // handle exception  
                Console.WriteLine("Exception caught: " + ex.Message);  
            }  
        }  
    }  
}  

另请参阅

使用 WCF 服务模型开发 Oracle 数据库应用程序