65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 应用程序与 Oracle 通过自定义对象之间的交互

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.79/5 (9投票s)

2011年1月1日

CPOL

3分钟阅读

viewsIcon

90779

downloadIcon

2368

C# 应用程序与 Oracle 通过自定义对象之间的交互

引言

作为一名开发人员,我非常喜欢 OOPS 及其在 C# 中的实现。当我们谈论 OOPS 时,我们大多数人都很乐于使用自定义对象(用户定义的对象)并在不同的应用程序层之间传输它们。真正的痛苦来自于我们计划将自定义对象发送到数据库或从数据库检索自定义对象时。更具体地说,通过 C# 实体实现数据库通信确实是一项具有挑战性的任务。

在我的职业生涯中,我主要使用 Oracle 和 C#。众所周知,这两个平台都是面向对象的,所以我决定将 OOPS 方法应用于数据库通信。

经过长期的努力和对各种可用选项的挖掘,我发现 ODP.NET 允许以对象传递的方式与数据库进行交互。

在本示例中,我参考了 ODP.NET (Oracle Data Provider for .NET, Release – 11.1)、Oracle 10g 和 Visual Studio 2008。

ODP.NET 是免费提供的,可以从 Oracle 站点下载可执行文件,网址为
http://www.oracle.com/technetwork/topics/dotnet/index-085163.html.

下面,我将详细讨论实施步骤。

将自定义对象发送到 Oracle 存储过程

//Person Entity – C# Custom Object
PersonBO objPersonBO 	= new PersonBO();
objPersonBO.Address 	= "Kolkata";
objPersonBO.Age 		= 20;
objPersonBO.Name 		= "Mr.Jhon";

//------ Establish the connection with Oracle-----///

//Insert the Person object into database table
OracleCommand cmd = new OracleCommand("ODP_RND_InsertPerson_Proc", objCon);
cmd.CommandType = CommandType.StoredProcedure; //Database store procedure

//Oracle Parameter
OracleParameter objParam = new OracleParameter();

//Denotes, we are going to pass a custom object
objParam.OracleDbType = OracleDbType.Object;

objParam.Direction = ParameterDirection.Input;

//Note: The UdtTypeName is case-sensitive - Should be in upper case
//This is a database object and physically exists in the database as custom // type
objParam.UdtTypeName = "ODP_RND_PERSON_TYPE";

//Attach the C# custom object as input parameter
objParam.Value = objPersonBO;

//Attach parameter to command object
cmd.Parameters.Add(objParam);

//Insert the UDT into the table
cmd.ExecuteNonQuery();

从上面的代码片段中,我们遇到了一个新的关键字“UdtTypeName”,它指的是 Oracle 用户类型。我们将在后面的讨论中对此进行解释。

从 Oracle 存储过程接收数据作为自定义对象

这需要几个步骤才能从数据库中提取数据。

//SQL statement
string strSql = "SELECT c.contact FROM odp_rnd_person_table c"

//------ Establish the connection with Oracle-----///

//Pass the SQL statement
OracleCommand objCmd 		= new OracleCommand(strSql, objCon);
objCmd.CommandType 		= CommandType.Text;

//Issue the statement
OracleDataReader objReader 	= objCmd.ExecuteReader();

//Fetch each row
while (objReader.Read())
{
      //Custom object
      PersonBO objPersonBO 	= new PersonBO();

       //Fetch the objects as a custom type
      objPersonBO 		= (PersonBO)objReader.GetValue(0);
}

我们完成了 C# 和 Oracle 之间的数据交换,这需要执行一些基本的步骤。我们将要讨论的更有趣的部分是自定义对象的创建。

需要命名空间

using System;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
using System.Xml.Serialization;
using System.Xml.Schema;

创建自定义类并使其派生自 IOracleCustomTypeIOracleCustomType 是一个用于在 C# 自定义类型和 Oracle 对象类型之间进行转换的接口。

public class PersonBO :  IOracleCustomType

PersonBO 下创建以下 public 属性,并使用 OracleObjectMappingAttribute 修饰它。OracleObjectMappingAttribute 需要在表示 Oracle 对象类型的自定义类型的每个成员上指定。此属性必须指定自定义类属性映射到的 Oracle 对象中属性的名称或从零开始的索引。这也允许自定义类型声明与 Oracle 对象类型不同的字段或属性名称。

[OracleObjectMappingAttribute("PNAME")]
 public virtual string Name{get;set;}
[OracleObjectMappingAttribute("ADDRESS")]
 public virtual string Address{get;set;}
[OracleObjectMappingAttribute("AGE")]
 public virtual decimal Age { get; set; }

PersonBO 下创建以下方法 FromCustomObject 并覆盖它。此接口方法通过在指定的 Oracle UDT 上分别设置属性来创建 Oracle 对象。

public virtual void FromCustomObject(OracleConnection objCon, IntPtr objUdt)
{
    //The FromCustomObject method is used to build an Oracle Object or   
    //Collection from a custom object by 
    //setting attribute or element values respectively through the 
    //OracleUdt.SetValue method.

    OracleUdt.SetValue(objCon, objUdt, "PNAME", this.Name);
    OracleUdt.SetValue(objCon, objUdt, "ADDRESS", this.Address);
    if (this.Age > 0) OracleUdt.SetValue(objCon, objUdt, "AGE", this.Age);
 }

PersonBO 下创建以下方法 ToCustomObject 并覆盖它。它为 Oracle 对象提供属性值以在自定义类型上设置。此接口方法使用指定的 Oracle UDT 初始化自定义对象。

public virtual void ToCustomObject(OracleConnection objCon, IntPtr objUdt)
{
   //The ToCustomObject method is used to initialize a custom object from the 
   //specified Oracle 
   //Object or Collection by retrieving attribute or element values 
   //respectively through the OracleUdt.GetValue method.
    
    this.Name    = ((string)(OracleUdt.GetValue(objCon, objUdt, "PNAME")));
    this.Address = ((string)(OracleUdt.GetValue(objCon, objUdt, "ADDRESS")));

    bool AgeIsNull = OracleUdt.IsDBNull(objCon, objUdt, "AGE");
    if ((AgeIsNull == false)) this.Age = 
		((decimal)(OracleUdt.GetValue(objCon, objUdt, "AGE")));
}

准备数据库对象

CREATE TABLE ODP_RND_PERSON_TABLE
(
  CONTACT  ODP_RND_PERSON_TYPE
)

上述脚本中的字段 CONTACT ODP_RND_PERSON_TYPE 类型,这是一个 Oracle 用户定义类型。

CREATE OR REPLACE type ODP_RND_Person_Type as object 
 (
     pname varchar2(30), 
     address varchar2(60), 
     age number(3)
) NOT FINAL

在这里,我们必须记住 C# 和 Oracle 用户定义类型的结构应该完全相同。

这是用于将数据插入表中的数据库存储过程。此过程接受上述类型作为输入参数。此类型封装了从 UI 级别传递的实际值。

在过程中,如果我们想访问单个属性的值,我们可以这样做

Person.pname, person.address, 等等。

CREATE OR REPLACE procedure 
 ODP_RND_InsertPerson_Proc(person IN ODP_RND_Person_Type) as
 begin
    Insert into ODP_RND_Person_Table values (person); 
 end

!! 享受编码的乐趣 !!

历史

  • 2011 年 1 月 1 日:初始发布
© . All rights reserved.