使用c#映射Oracle UDT而不使用存储过程

时间:2017-03-31 21:16:35

标签: c# .net oracle mapping oracle-type

我需要在c#应用程序中映射Oracle Object类型。网上有大量的例子,包括这里和其他网站/博客,但所有这些都包括使用存储过程,我不应该这样做。

过去两天我一直在搜索,最接近的是 docs.oracle.com 上的一篇文章,但它没有一个例子。

请允许任何人举例说明如何实现这一目标吗?

我使用Oracle.DataAccess类与我的数据库进行通信,并使用下面给出的简单UDT:

create or replace 
TYPE "MYNUMBER_TYPE" AS OBJECT (
  MyNumber NUMBER(13)
)
INSTANTIABLE NOT FINAL;

1 个答案:

答案 0 :(得分:4)

如果要执行PL / SQL,可以执行以下操作。这足以摧毁世界统治本身。几乎。

注意,这没有经过测试,因为我这里没有Oracle DB。但是我在我目前的一个项目中使用这种方法。

cmd = New OracleCommand("declare " +
          "    lSomeVarchar2 varchar2(255); " +
          "    lSomeNumber number; " +
          "    lSomeLong long; " +
          "begin " +
          "  loop " +
          "  --do something fancy here  " +
          "  end loop; " +
          "  --you can pass variables from outside: " +
          " :parameterNumber:= lSomeNumber ; " +
          " :parameterVarChar := lSomeLong; " +
          "end;", conn);
          //make these of direction output and you can get values back
cmd.Parameters.Add("parameterNumber", OracleDbType.Integer).Direction = ParameterDirection.Output;
cmd.Parameters.Add("parameterVarChar", OracleDbType.VarChar).Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();

//now you can get the values using something like
int cNumber = (int)cmd.Parameters("parameterNumber").Value;
String myString = (String) cmd.Parameters("parameterNumber").Value;

编辑3又回答你的评论:

使用 IOracleCustomType-Interface : 同样,我无法测试它,因为我仍然无法访问Oracle数据库。但是,让我们做一些魔术。

步骤1:在C#代码中创建一个继承自IOracleCustomType的自定义类型:

[OracleCustomTypeMapping("C##USER.MYNUMBER_TYPE")]
public class MyCustomClass : IOracleCustomType

然后,对于每个类成员,您必须指定Oracle链接。在下面的名称" MyNumber"来自您问题中的自定义类型规范。

[OracleObjectMappingAttribute("MyNumber")]
public virtual int cNumber{get; set;}

此外,您必须覆盖方法 FromCustomObject ToCustomObject

//this one is used to map the C# class-object to Oracle UDT
public virtual void FromCustomObject(OracleConnection conn, IntPtr object){
    OracleUdt.SetValue(conn, object, "MyNumber", this.cNumber);
}

//and this one is used to convert Oracle UDT to C# class
public virtual void ToCustomObject(OracleConnection conn, IntPtr object){
    this.cNumber = ((int)(OracleUdt.GetValue(conn, object, "MyNumber")));
}

第2步:在数据库中创建您已经执行的自定义类型。所以我在此不再重复。

第3步:现在我们已经成立了。我们来试试吧:

//first create your SQL-Statement
String statement = "SELECT MY_CUSTOM_TYPE_COLUMN FROM MY_SUPER_TABLE";

//then set up the database connection
OracleConnection conn = new OracleConnection("connect string");
conn.Open();
OracleCommand cmd = new OracleCommand(statement, conn);
cmd.CommandType = CommandType.Text;

//execute the thing
OracleDataReader reader = cmd.ExecuteReader();

//get the results
while(reader.Read()){
    MyCustomClass customObject = new MyCustomClass();
    //get the Object, here the magic happens
    customObject = (MyCustomClass)reader.GetValue(0);

    //do something with your object

}