2008-11-11 14 views
6

Ich bin relativ neu zu NHibernate, aber habe es für die letzten paar Programme verwendet und ich bin verliebt. Ich bin zu einer Situation gekommen, in der ich Daten aus 4-5 Datenbanken in einer einzigen Datenbank zusammenfassen muss. Spezifisch sind es serielle Daten. Jede Datenbank hat ihre eigene Zuordnungsdatei, aber letztendlich haben alle Entitäten die gleiche Grundstruktur (serielle Klasse).NHibernate: Eine Basisklasse, mehrere Zuordnungen

Ich verstehe, NHibernate möchte eine Zuordnung pro Klasse, und so war mein erster Gedanke, eine Basis Serial Class zu haben und dann erben für jede andere Datenbank und erstellen Sie eine eindeutige Zuordnungsdatei (die geerbte Klasse würde Null Inhalt haben). Dies sollte gut funktionieren, um alle Daten zu erfassen und die Objekte zu füllen. Was ich dann gerne machen würde, ist diese geerbten Klassen (nicht sicher, was der richtige Ausdruck ist) in der Basisklasse-Tabelle zu speichern, indem ich die Basisklassenzuordnung verwende.

Das Problem ist, ich habe keine Ahnung, wie Sie NHIbernate zwingen, eine bestimmte Zuordnungsdatei für ein Objekt zu verwenden. Das Übergeben der geerbten Klasse an die Basisklasse bewirkt nichts, wenn 'session.save()' verwendet wird (es klagt über kein Mapping).

Gibt es eine Möglichkeit, explizit anzugeben, welches Mapping verwendet werden soll? Oder gibt es nur ein OOP-Prinzipal, das ich vermisse, um eine geerbte Klasse genauer in die Basisklasse zu übertragen? Oder ist diese Idee nur schlecht?

Alle Vererbung Sachen, die ich in Bezug auf NHibernate finden konnte (Kapitel 8) scheint nicht vollständig für diese Funktion anwendbar, aber ich könnte falsch liegen (die Tabelle-pro-Beton-Klasse aussieht vielleicht nützlich, aber ich kann mich nicht völlig damit beschäftigen, wie NHibernate herausfindet, was zu tun ist.

Antwort

4

Ich weiß nicht, ob das hilft, aber ich würde das im Grunde nicht versuchen.

Grundsätzlich denke ich, dass Sie möglicherweise leiden unter "Golder Hammer" -Syndrom: Wenn Sie einen wirklich WIRKLICH schönen Hammer haben (dh Hibernate (und ich teile Ihre Meinung dazu; es ist ein großartiges Werkzeug)), sieht alles wie ein Nagel.

Ich würde im Allgemeinen versuchen, einfach eine "manuelle Konvertierung" -Klasse zu haben, d. H. Eine, die Konstruktoren hat, die die Hibernate-Klassen für Ihre individuellen seriellen Klassen übernehmen und die Daten einfach in ihr eigenes spezifisches Format kopieren; dann kann Hibernate es einfach mit einer eigenen Zuordnung in die (einzelne) Datenbank serialisieren.

Effektiv, der Grund, warum ich denke, dies ist eine bessere Lösung ist, dass, was Sie effektiv versuchen zu tun ist, asymmetrische Serialisierung in Ihrer Klasse haben; d. h. gelesen von einer Datenbank in Ihrer abgeleiteten Klasse, schreibe in eine andere Datenbank in Ihrer Basisklasse. Daran ist eigentlich nichts Schreckliches, außer dass es sich grundsätzlich um einen unidirektionalen Prozess handelt; Wenn Sie wirklich von einer Datenbank in die andere konvertieren möchten, machen Sie einfach die Konvertierung und sind damit fertig.

+0

Yah, ich stimme zu, das macht Sinn. Ich habe auf eine Silberkugel gehofft, aber was du erwähnt hast, wird perfekt funktionieren. – anonymous

2

Dies könnte helfen;

Using NHibernate with Multiple Databases

Aus dem Artikel;

Einführung

... beschrieben NHibernate mit ASP.NET verwendet wird; Es bietet Richtlinien für Kommunikation mit einer einzigen Datenbank. Aber es ist manchmal notwendig, gleichzeitig mit mehreren Datenbanken kommunizieren. Damit NHibernate dies tun kann, muss eine Sitzungsfactory für jede Datenbank existieren, die Sie mit kommunizieren werden. Aber, wie oft der Fall mit mehreren Datenbanken ist, werden einige der Datenbanken selten verwendet. So kann es eine gute Idee sein, nicht Sitzungsfabriken zu erstellen, bis sie tatsächlich benötigt werden. Dieser Artikel nimmt auf, wo der vorherige NHibernate mit ASP.NET-Artikel aufgehört hat und die Implementierungsdetails dieses einfach klingenden Ansatzes beschreibt. Obwohl sich der vorherige Artikel auf ASP.NET konzentrierte, wird der folgende Vorschlag in ASP.NET und .NET unterstützt.

...

Das erste, was zu tun ist, wenn mit mehreren Datenbanken arbeiten, ist zu configure richtigen Kommunikation. Erstellen Sie für jede -Datenbank eine separate Konfigurationsdatei, legen Sie sie alle in einen zentralen Konfigurationsordner , und verweisen Sie sie anschließend über web/app.config auf .

...

0

Ich bin nicht 100% sicher, dass dies tun, was ich brauche, aber ich fand diese googeln heute über NHibernate und anonyme Typen:

http://infozerk.com/averyblog/refactoring-using-object-constructors-in-hql-with-nhibernate/

Die Interessanter Teil (für mich bin ich neu) ist das 'neue' Schlüsselwort in der HQL Auswahlklausel. Also, was ich tun könnte ist, wählen Sie die SerialX von DatabaseX mit MappingX, und übergeben Sie es an einen Konstruktor für SerialY (die allgemeine/Basis Serial). Jetzt habe ich SerialY von mappingX/databaseX generiert, und (hoffentlich) könnte ich dann session.save und NHibernate mapyY/databaseY verwenden.

Der Grund, warum ich das mag, ist einfach nicht zwei Klassen mit den gleichen Daten bestehen (denke ich!). Es gibt wirklich keinen funktionalen Unterschied zwischen dem Zurückgeben einer Liste von SerialX, dem Iterieren und Generieren von SerialY und dem Hinzufügen zu einer neuen Liste (die erste und die beste gegebene Antwort).

Dies hat nicht den allgemeineren Vorteil, nützliche Fälle für NHibernate-Mappings mit Vererbung zu machen, aber ich denke, dass es die begrenzten Sachen machen wird, die ich will.

0

Obwohl es wahr ist, benötigen Sie eine Mapping-Datei/Klasse für jede dieser Tabellen, es gibt nichts, was Sie daran hindert, alle diese Klassen eine gemeinsame Schnittstelle implementieren zu lassen.

Sie können dann aggregieren sie alle zusammen in einer einzigen Sammlung in Ihrer Anwendungsschicht (Ie Liste), wobei jede dieser Klassen Liste implementieren)

Sie müssen wahrscheinlich einige Sanitär schreiben Überblick über die Sitzung zu halten Speichern Sie es unter (da Sie auf mehrere Datenbanken abzielen), wenn Sie Aktualisierungen vornehmen möchten. Aber der Prozess dafür hängt davon ab, wie Sie die Dinge eingerichtet haben.

0

Ich schrieb eine wirklich lange Post mit Code und alles, um auf Dan zu antworten. Es endete damit, dass ich das Offensichtliche vermisste.

public class Serial 
{ 
    public string SerialNumber {get; set;} 
    public string ItemNumber {get; set;} 
    public string OrderNumber {get; set;} 
} 

...

Serial serial = sessionX.get(typeof(Serial), someID); 
sessionY.save(serial); 

NHibernate sollte mappingX für die get und mappingY für das Speichern verwenden, da die Sitzungen nicht mit anderen geteilt werden, und die Zuordnung an die Sitzung gebunden. So kann ich zwei Zuordnungen haben, die auf dieselbe Klasse verweisen, weil es in einer bestimmten Sitzung nur eine einzige Zuordnung zur Klassenbeziehung gibt.

Zumindest denke ich, dass das der Fall ist (kann atm nicht testen).

Leider ist dieser spezielle Fall wirklich langweilig und nicht nützlich. In einem anderen Programm der gleichen Domäne leite ich von der Basisklasse für einen bestimmten Teil der Geschäftslogik ab. Ich wollte keine Mapping-Datei erstellen, da es nur einen kleinen Teil des Codes vereinfachen sollte. Wie auch immer, ich konnte es aus den gleichen Gründen wie meine erste Frage nicht in NHibernate arbeiten lassen und habe die Methode, die McWafflestix beschreibt, um es zu umgehen (da es minderwertig war) gemacht.

sagte, dass ich dies über google gefunden haben:

http://jira.nhibernate.org/browse/NH-662

Das ist genau die gleiche Situation, und es erscheint (möglicherweise) adressiert in NH 2.1+? Ich habe es noch nicht weiter verfolgt.

(Anmerkung: Dan, in meinem Fall bekomme ich von mehreren db's, schreibe nur eins. Ich bin immer noch an Ihrem Vorschlag über die Schnittstelle interessiert, weil ich denke, dass das eine gute Idee für andere Fälle ist. Würdest du definieren Das Mapping gegen die Schnittstelle? Wenn ich versuche, eine Klasse zu speichern, die die Schnittstelle implementiert, die keine Zuordnungsdefinition hat, würde NHibernate die Schnittstellenzuordnung verwenden? Oder müsste ich leere Unterklassen im Mapping für jede Klasse deklarieren, die die Zuordnung implementiert Interface Mapping?)

Verwandte Themen