2009-10-01 12 views
9

アプリケーションのデータアクセス層は、OracleのUDT機能を使用します。 UDTオブジェクトはデータベースとの間でのみやり取りされます。OracleObjectMappingAttributeを使用せずにODP.NETを使用してOracle UDTからマップする方法はありますか。

現時点では、ODP.NETで提供されている関数を使用してカスタムクラスを生成しています(コードベースでは本当に恐ろしい外観のクラスを作成します)。

別のマッピングクラスを使用して、カスタムクラスをビジネスオブジェクトの1つにマッピングします(保存時に戻す)。

私はこれを行うより良い方法を探しています。

私は、生成されたクラスを削除し、IOracleCustomTypeを実装したマッピングクラスを作成すると思っていました。 From/ToCustomObjectメソッドは、UDTからビジネスオブジェクトにマップします。 しかし、これは私が試したときに私に問題を引き起こした - 私は、エラー "オブジェクトの属性は、カスタムタイプのメンバーにマップされていない"。 2つの方法と同様に、マッピングクラスにも属性が必要です(UDTの各項目に1つの属性が必要です)。

たとえば、ワークフローUDTには、ステータス、作成時刻、および作成者の3つの項目が含まれています。 私のUDTはいいと簡単です:私はそれがで終わるしたいビジネス・オブジェクトがあるので

TYPE workflow_type AS OBJECT 
(status         VARCHAR2(8) 
,created_by        VARCHAR2(30) 
,created_datetime   DATE 
); 

私はOracleのコードを追加することなく、一方から他方へ取得したい
public class Workflow 
{ 
    /// <summary> 
    /// Gets the status of the workflow. 
    /// </summary> 
    /// <value>The status.</value> 
    public string Status { get; private set; } 

    /// <summary> 
    /// Gets the Windows Logon Id of the user performing the action 
    /// </summary> 
    public string CreatedBy{ get; private set; } 
    /// <summary> 
    /// Gets the time of the action 
    /// </summary> 
    public DateTime CreatedTime { get; private set; } 
} 

ビジネスオブジェクトに追加します。

だから私の考えは、このようにマッピングクラスを作成することでした。

public class WorkFlowMapper : IOracleCustomType 
{ 
    public BusinessObjects.WorkFlow BusinessObject {get; private set;} 

    public WorkFlowMapper(BusinessObjects.WorkFlow businessObject) 
    { 
     BusinessObject = businessObject; 
    } 

    public WorkFlowMapper(){} 

    public void FromCustomObject(OracleConnection con, IntPtr pUdt) 
    { 
     OracleUdt.SetValue(con, pUdt, "STATUS", BusinessObject.Status); 
     OracleUdt.SetValue(con, pUdt, "CREATED_BY", BusinessObject.CreatedBy); 
     OracleUdt.SetValue(con, pUdt, "CREATED_DATETIME", BusinessObject.CreatedTime); 
    } 

    public void ToCustomObject(OracleConnection con, IntPtr pUdt) 
    { 

     BusinessObject = new BusinessObjects.WorkFlow(
      (string)OracleUdt.GetValue(con, pUdt, "STATUS"), 
      (string)OracleUdt.GetValue(con, pUdt, "CREATED_BY"), 
      (string)OracleUdt.GetValue(con, pUdt, "CREATED_DATETIME") 
     ); 
    } 
} 

// Factory to create an object for the above class 
[OracleCustomTypeMappingAttribute("MYUSER.WORKFLOW_TYPE")] 
public class CurrencyExposureFactory : IOracleCustomTypeFactory 
{ 

    public virtual IOracleCustomType CreateObject() 
    { 
     WorkFlowMapper obj = new WorkFlowMapper(); 
     return obj; 
    } 
} 

しかし、これは、生成ODP.NETのようにマップされる属性ごとにOracleObjectMappingAttributeを必要とする要件(のおかげで動作しません。クラス)。 これはまったく使っていないので、これは本当にばかばかしいようです。 実際に、私はちょうど三行に追加することで、動作するように私のマッピングクラスを取得することができます。

[OracleObjectMappingAttribute("STATUS")] public string a; 
    [OracleObjectMappingAttribute("CREATED_BY")] public string b; 
    [OracleObjectMappingAttribute("CREATED_DATETIME")] public DateTime c; 

は確かに、このような恐ろしいハックを入れてより良い方法がなければなりませんか?後で、これらの変数はまったく使用されません。ODP.NETは、型をマップするために必要なように見えますが、これは別の方法で実現できると思います。 考えますか?

答えて

2

余分な属性についてはどうですか? .netのクラスとフレームワーク(例えばWCF)には、すでにかなりの量の属性があります。嫌いな属性は、.NETを嫌うこととほとんど同じです。

とにかく、devartのOracleプロバイダ(http://www.devart.com/dotconnect/oracle/)の可能性を探ることができます。彼らも無料版を持っています。 udtsを扱うのは、属性ではない文字列に基づいています。

+4

悪い点は、それらが必要ではないということです。プロパティー自体は取得または設定されません。必要なのは、すべてのUDTプロパティーにOracleObjectMappingAttributeのいずれかが必要なためです。あるクラスの中で一度も使用されていない公共のプロパティをたくさん持っているのは狂っているようです(はい、彼らも公開しなければなりません)。だから私はそれが属性ではなく、私が疑問に思っているパブリックプロパティの必要性だと思います。 – David

+0

ああ、他のオラクルプロバイダのリンクに感謝します(残念ながら、これは個人的に私が働いている場所で使用されているODP.NETだけです) – David

+0

マッピングする必要があるため、実際にコードに「重複」がありますコードでは、属性とマップするが、私はそれが大きな問題だとは思わない。それは問題ですが、大きな問題はありません。 – Theo

0

BusinessObjectをプライベートメンバーとして設定し、属性をそれぞれのプロパティにマップできます。

これは機能を提供しませんが、少なくとも使用すると正しく機能します。

関連する問題