2009-10-01 3 views
9

Die Datenzugriffsebene in unserer Anwendung wird die UDT-Funktionalität von Oracle verwenden. Wir werden nur UDT-Objekte zu und von der Datenbank übergeben.Wie kann ich Oracle ODTs mit ODP.NET abbilden, ohne OracleObjectMappingAttribute zu verwenden?

Im Moment generieren wir die benutzerdefinierten Klassen mit der Funktion, die mit ODP.NET geliefert wird (was eine wirklich schrecklich aussehende Klasse erzeugt, die wir wirklich nicht in unserer Codebasis haben wollen).

Wir verwenden dann eine separate Zuordnungsklasse, um die benutzerdefinierte Klasse einem unserer Geschäftsobjekte zuzuordnen (und zurück beim Speichern).

Ich versuche, einen besseren Weg zu finden, dies zu tun.

Ich dachte, ich würde nur mit den generierten Klassen weg und schreiben Sie einfach eine Mapping-Klasse, die IOracleCustomType implementiert. Die From/ToCustomObject-Methoden würden dann von meinem UDT zu meinen Geschäftsobjekten mappen. Dies verursachte jedoch Probleme, wenn ich es versuchte - ich habe den Fehler "Objektattribut ist nicht zugeordnet zu einem benutzerdefinierten Typ Mitglied". Es scheint, dass auch die beiden Methoden, ich brauche auch Attribute in meiner Mapping-Klasse - ein Attribut für jedes Element in der UDT.

Zum Beispiel - ein Workflow UDT enthält drei Elemente - einen Status, erstellt Zeit und erstellt von. Mein UDT ist schön und einfach:

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

Da das Objekt Geschäft Ich will es in am Ende:

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

ich von einem zum anderen gelangen möchten, ohne Oracle-Code hinzufügen zu müssen zum Geschäftsobjekt.

So war mein Gedanke eine Zuordnung Klasse wie folgt zu erstellen:

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

Aber dank des Müssens OracleObjectMappingAttribute der Anforderung für jedes Attribut zugeordnet werden nicht funktioniert (wie in der ODP.NET erzeugt Klassen). Das erscheint wirklich dumm, da ich sie überhaupt nicht benutzen werde. In der Tat kann ich meine Mapping-Klasse zu arbeiten, nur um in drei Zeilen hinzu:

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

Sicherlich muss es in einem solchen schrecklichen Hack einen besseren Weg, als setzen? Schließlich werden diese Variablen überhaupt nicht verwendet - ODP.NET scheint sie nur zu brauchen, um den Typ zu bekommen - aber ich hätte gedacht, dass dies auf andere Weise erreicht werden könnte. Gedanken?

Antwort

2

Was ist so schlimm an diesen zusätzlichen Attributen? In den .NET-Klassen und -Frameworks (z. B. WCF) gibt es bereits eine enorme Menge an Attributen. Das Ablehnen von Attributen ist fast das Gleiche wie das Abnicken von .NET.

Wie auch immer, Sie können die Möglichkeiten des Oracle-Providers von Devart (http://www.devart.com/dotconnect/oracle/) erkunden. Sie haben auch eine kostenlose Version. Der Umgang mit udts basiert auf Strings, nicht auf Attributen.

+4

Was schlecht ist, ist, dass sie nicht benötigt werden. Die Eigenschaften selbst werden nie abgerufen oder festgelegt. Der einzige Grund, warum sie benötigt werden, ist, dass jede UDT-Eigenschaft eines dieser OracleObjectMappingAttribute benötigt. Es scheint einfach verrückt zu sein, eine Menge öffentlicher Eigenschaften in einer Klasse zu haben, die niemals benutzt werden (und ja, sie müssen auch öffentlich sein!). Also denke ich, es ist die Notwendigkeit für die öffentlichen Eigenschaften, die ich in Frage stelle, anstatt die Attribute. – David

+0

Oh, und danke für den anderen Orakel Anbieter Link (leider wird mir das nicht persönlich helfen, da wo ich arbeite ist es nur ODP.NET, das verwendet wird) – David

+0

Es gibt tatsächlich einige 'Duplikation' im Code, weil Sie zuordnen müssen im Code und mit Attributen zu kartografieren, aber ich denke einfach nicht, dass es ein großes Problem ist. Es ist ein Problem, aber kein großer. – Theo

0

Sie können Ihr BusinessObject als ein privates Mitglied festlegen und die Attribute den entsprechenden Eigenschaften zuordnen.

Während dies keine Funktionalität zur Verfügung stellt, würden sie zumindest funktionieren, wenn sie verwendet werden.

Verwandte Themen