【问题标题】:Mapping Oracle UDT using c# without stored procedure使用 c# 映射 Oracle UDT 而无需存储过程
【发布时间】:2017-08-26 06:18:47
【问题描述】:

我需要在我的 c# 应用程序中映射一个 Oracle 对象类型。网上有大量示例,包括此处和其他网站/博客,但所有示例都包含使用存储过程,我不应该这样做。

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

谁能举例说明如何实现这一点?

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

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

【问题讨论】:

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


    【解决方案1】:

    如果您想执行 PL/SQL,您可以执行以下操作。这足以撕裂世界统治本身。差不多了。

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

    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;
    

    EDIT 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;}
    

    此外,您必须重写方法 FromCustomObjectToCustomObject

    //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
    
    }
    

    【讨论】:

    • 谢谢你的回答,但我的意思是如何在c#中通过自定义类型实现映射。我读到的文章提到了IOracleCustomType 和其他接口......我不太明白,但也许你知道这是怎么回事......
    • customObject = (MyCustomClass)reader.GetValue(0) throws >>>'dataSource='DB' schemaName='C##USER' typeName='MYNUMBER_TYPE''的自定义类型映射未指定或无效
    • 啊,好点,你必须在你的类定义之前添加自定义类型映射[OracleCustomTypeMapping("C##USER.MYNUMBER_TYPE")]。编辑了我上面的帖子
    • 仍然是同样的错误 :) 我在另一个问题 (stackoverflow.com/questions/43172178/…) 中发布了我的完整代码。有兴趣的可以去看看...
    猜你喜欢
    • 2017-05-25
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 2017-08-22
    • 1970-01-01
    • 2015-04-07
    相关资源
    最近更新 更多