2010-02-18 13 views
5

Ich verwende zwei Klasse NiceCustomer & RoughCustomer, die die Schnittstelle ICustomer impliment.Wie eine Schnittstelle in Nhibernate zuordnen?

Die ICustomer hat vier Eigenschaften. Sie sind:

  1. Property Id() As Integer
  2. Property Name() As String
  3. Property IsNiceCustomer() As Boolean
  4. ReadOnly Property AddressFullText() As String

Ich weiß nicht, wie die Schnittstelle zur Karte ICustomer, in die Datenbank.

Ich bekomme einen Fehler wie diese in der inneren Ausnahme.

Ein Verband bezieht sich auf eine nicht zugeordnete Klasse: ICustomer

Ich fliessend und NHibernate.

+0

Ich glaube nicht, dass Sie irgendeine Schnittstelle als solche zuordnen müssen. Könnten Sie bitte Ihre Mapping-Dateien posten? Danke –

+0

Danke für die Antwort Mahesh. Aber wie Kevin gesagt hat, können wir keine Schnittstelle in Nhibernate abbilden. Ich habe die Schnittstelle zu einer Basisklasse geändert. – Josh

Antwort

0

Es ist nicht möglich, eine Schnittstelle in nhibernate abzubilden. Wenn es Ihr Ziel ist, mit einem gemeinsamen Typ abfragen zu können, um beide Kundentypen abzurufen, können Sie eine polymorphe Abfrage verwenden. Lassen Sie einfach beide Klassen die Schnittstelle implementieren und ordnen Sie die Klassen normal zu. Sehen Sie diese Referenz:

https://www.hibernate.org/hib_docs/nhibernate/html/queryhql.html (Abschnitt 11,6)

+0

Ich habe auch eine polymorphe Abfrage versucht, aber es funktioniert nicht. Immer noch Probleme mit diesem nicht zugeordneten Interface-Kunden. Also wurde es jetzt eine Basisklasse, die gut funktioniert. Vielen Dank Kevin. – Josh

+0

"Es ist vollkommen akzeptabel, dass die benannte persistente Klasse eine Schnittstelle ist. Sie würden dann implementierende Klassen dieser Schnittstelle mit dem Element deklarieren." von http://knol.google.com/k/fabio-maulo/nhibernate-chapter-5-basic-o-r-mapping/1nr4enxv3dpeq/8# – Neal

+3

Link in dieser Antwort ist gebrochen. Bitte aktualisieren Sie den Link oder fügen Sie weitere Details zu Ihrer Antwort hinzu. –

0

wie Sie abfragen? Wenn Sie HQL verwenden müssen Sie die Schnittstelle des Namensraum mit einer HBM-Datei mit dieser Zeile importieren:

<import class="name.space.ICustomer, Customers" /> 

Wenn Sie Kriterien verwenden, sollten Sie nur in der Lage sein, für ICustomer abfragen und es wird sowohl Kunden zurück Arten.

Wenn Sie Abbildung einer Klasse, die ein Kunde auf sie entweder durch eine HasMany, HasManyToMany oder Referenzen dann müssen Sie die generische Form verwenden:

References<NiceCustomer>(f=>f.Customer) 

Wenn Sie es entweder mit bewältigen wollen, Sie werden sie Unterklassen

Subclassmap<NiceCustomer> 

in diesem Fall denken lassen, muss ich Ihnen die Basisklasse Kunde und dass in der äußeren Klasse für den generischen Typparameter verwenden benötigen:

References<Customer>(f=>f.Customer) 

Unabhängig davon, sollten Sie Ihr Domänenmodell nicht ändern, um damit fertig zu werden, es sollte immer noch einen ICustomer für die äußere Klasse haben.

Ich bin nicht sicher, ob das 1.0RTM das generische Formular für Referenzen funktioniert, aber ein schneller Scan der Änderungen sollte die Änderung zeigen, die ich denke, ist eine zweizeilige Ergänzung.

3

Sie können direkt zu Schnittstellen in NHibernate zuordnen, indem Sie einen EmptyInterceptor während der Konfigurationsphase einstecken.Die Aufgabe dieses Interceptors besteht darin, Implementierungen für die Schnittstellen bereitzustellen, die Sie in Ihren Mapping-Dateien definieren.

public class ProxyInterceptor : EmptyInterceptor 
{ 
    public ProxyInterceptor(ITypeHandler typeHandler) { 
     // TypeHandler is a custom class that defines all Interface/Poco relationships 
     // Should be written to match your system 
    } 

    // Swaps Interfaces for Implementations 
    public override object Instantiate(string clazz, EntityMode entityMode, object id) 
    { 
     var handler = TypeHandler.GetByInterface(clazz); 
     if (handler == null || !handler.Interface.IsInterface) return base.Instantiate(clazz, entityMode, id); 
     var poco = handler.Poco; 
     if (poco == null) return base.Instantiate(clazz, entityMode, id); 

     // Return Poco for Interface 
     var instance = FormatterServices.GetUninitializedObject(poco); 
     SessionFactory.GetClassMetadata(clazz).SetIdentifier(instance, id, entityMode); 

     return instance; 
    } 

} 

Danach können alle Beziehungen und Zuordnungen als Schnittstellen definiert werden.

public Parent : IParent { 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public IChild Child { get; set; } 
} 

public Child : IChild { 
    public int ID { get; set; } 
    public string Name { get; set; } 
} 

public class ParentMap : ClassMap<IParent> 
{ 
    public ParentMap() 
    { 
     Id(x => x.ID).GeneratedBy.Identity().UnsavedValue(0); 
     Map(x => x.Name) 
    } 
} 

... 

Diese Art der Technik ist groß, wenn Sie echte Entkopplung des ORM erreichen wollen, alle Konfigurations/Mappings in einem separaten Projekt platzieren und nur Referenzierung Schnittstellen. Ihre Domänenebene wird dann nicht mit ORM verschmutzt und Sie können sie später bei Bedarf ersetzen.

+0

Können Sie ein Beispiel für die Verwendung des ProxyInterceptor in der Konfiguration hinzufügen? Ich fange gerade gerade an Fluent Nhibernate zu benutzen und bin nicht vertraut genug mit dem Config-Teil, um zu wissen, wo ich den Proxy ... –

+0

Ich konnte es funktioniert, aber das Problem ist, dass der Domain-Layer noch übermäßig verschmutzt ist ORM-spezifische Methoden - in erster Linie die Setter auf Eigenschaften. Das ORM muss in der Lage sein, einen Wert für jedes Feld zu setzen, während ich im Domain-Objekt NICHT das Ändern des Id-Feldes eines Objekts ermöglichen möchte (dasselbe gilt für viele andere schreibgeschützte Eigenschaften). –

Verwandte Themen