2008-10-28 3 views
12

Ich habe eine Oracle-Datenbank und eines der Felder ist ein Datumsbereich Feld. Es wird im Grunde nur als VARCHAR (40) im Format JJJJ/MM/TT-JJJJ/MM/TT in der Datenbank gespeichert. Ich will es in nHibernate zu einer benutzerdefinierten Klasse Plan Ich mag diesesnHibernate Mapping zu benutzerdefinierten Typen

public class DateTimeRange 
{ 
    public DateTimeRange(DateTime fromTime, DateTime toTime) 
    { 
     FromTime = fromTime; 
     ToTime = toTime; 
    } 

    public override string ToString() 
    { 
     return String.Format("{0} to {1}", FromTime.ToString("HH:mm:ss"), ToTime.ToString("HH:mm:ss")); 
    } 

    public DateTime FromTime { get; set; } 

    public DateTime ToTime { get; set; } 
} 

erstellt haben, Wie kann ich benutzerdefinierte Klassen wie diese Karte?

Antwort

17

Sie müssen Ihren eigenen IUserType implementieren.

Einzelheiten finden Sie unter blog post. Ich werde auch den relevanten Abschnitt unten einfügen, falls der Blog verschwindet.

In NHibernate ist ein benutzerdefinierter Zuordnungstyp eine Klasse, die entweder von den Schnittstellen IUserType oder ICompositeUserType abgeleitet wird. Diese Schnittstellen enthalten mehrere Methoden, die implementiert werden müssen, aber für unsere Zwecke werden wir uns auf zwei davon konzentrieren. Folgendes berücksichtigen.

public class TypeClassUserType : IUserType 
    { 


    object IUserType.NullSafeGet(IDataReader rs, 
     string[] names, 
    object owner) { 

    string name = NHibernateUtil.String.NullSafeGet(rs, 
    names[0]) as string; 

    TypeClassFactory factory = new TypeClassFactory(); 
    TypeClass typeobj = factory.GetTypeClass(name); 
    return typeobj; 
    } 

    void IUserType.NullSafeSet(IDbCommand cmd, 
    object value, 
    int index) { 

     string name = ((TypeClass)value).Name; 
    NHibernateUtil.String.NullSafeSet(cmd, name, index); 
    } 
    } 

diese Klasse erstellt haben, kann ich jetzt Karte explizit den Zusammenhang zwischen ActualClass und typeclass als einfache Eigenschaft auf der ActualClass Mapping.

<property 
    name="Type" 
    column="TypeName" 
    type="Samples.NHibernate.DataAccess.TypeClassUserType, 
     Samples.NHibernate.DataAccess" /> 

Als NHibernate im Begriff ist, eine Instanz von ActualType retten, wird es eine neue Instanz von TypeClassUserType und rufen Sie die NullSafeSet Methode laden und erstellen. Wie Sie dem Hauptteil der Methode entnehmen können, entziehe ich einfach den Namen aus der zugeordneten Eigenschaft (übergeben als Wertparameter) und setze den extrahierten Namen als den Wert des Parameters, der in der Datenbank gesetzt werden soll. Das Endergebnis ist, dass, obwohl die Type-Eigenschaft von ActualClass TypeClass im Domänenmodell ist, nur die Name-Eigenschaft des TypeClass-Objekts in der Datenbank gespeichert wird. Das Gegenteil ist auch richtig. Wenn NHibernate eine Instanz von ActualType aus der Datenbank lädt und eine Eigenschaft meines benutzerdefinierten Zuordnungstyps findet, lädt es meinen benutzerdefinierten Typ und ruft die NullSafeGet-Methode auf. Wie Sie sehen können, ruft meine Methode den Namen aus den zurückgegebenen Daten ab, ruft meine Flyweight-Factory auf, um die korrekte Instanz von TypeClass abzurufen, und gibt diese Instanz dann tatsächlich zurück. Die Typauflösung erfolgt transparent für meine Datenzugriffsklassen (und sogar für NHibernate selbst).

+0

Hallo TheSoftwareJedi, Könnten Sie bitte helfen, den Link von Ihnen in der Post erwähnt zu überprüfen? es ist nicht gefunden. Könnten Sie bitte einen verfügbaren Link dazu geben? Vielen Dank. –

+0

Ich entfernte den Link von der Antwort. Ich habe keinen anderen Link und habe sogar den Bruch der Verbindung vorweggenommen, seit ich den relevanten Abschnitt in den Text der Antwort eingefügt habe. – TheSoftwareJedi

+0

https://web.archive.org/web/20100516024604/http://blogs.msdn.com/howard_dierking/archive/2007/04/23/nhibernate-custom-mapping-types.aspx –