2009-03-19 12 views
3

Ich verwende eine benutzerdefinierte benannte Abfrage mit NHibernate, die eine Auflistung von Person-Objekten zurückgeben soll. Die Person-Objekt ist nicht mit einer NHibernate-Mapping zugeordnet, was bedeutet, ich die folgende Ausnahme erhalten:Verwenden der nicht zugeordneten Klasse mit NHibernate Name der Abfrage

System.Collections.Generic.KeyNotFoundException: Der angegebene Schlüssel im Wörterbuch nicht vorhanden war.

Es geworfen wird, wenn die Session erstellt wird, weil es nicht die Klassennamen finden kann, wenn er ruft NHibernate.Cfg.Mappings.GetClass (String classname). Das ist alles ziemlich verständlich, aber ich frage mich, ob es irgendeinen Weg gibt, NHibernate zu sagen, die Klasse zu benutzen, obwohl ich kein Mapping dafür habe?

Antwort

0

Um dies zu lösen, habe ich den TupleToPropertyResultTransformer verwendet und die Liste der Eigenschaftswerte bereitgestellt. Hierfür gibt es einige Einschränkungen. Der wichtigste ist, dass die SQL-Abfrage die Ergebnisse in derselben Reihenfolge zurückgeben muss, in der Sie dem Konstruktor TupleToPropertyResultTransformer Ihre Eigenschaften bereitgestellt haben.

Auch die Eigenschaftstypen werden abgeleitet, daher müssen Sie vorsichtig mit Dezimalspalten sein, die nur ganzzahlige Werte usw. zurückgeben. Außerdem bietet die Verwendung des TupleToPropertyResultTransformers eine relativ einfache Möglichkeit, eine Sammlung von Objekten ohne explizite Zuordnung zurückzugeben die Objekte in NHibernate.

0

Mit der Klasse würde NHibernate grundsätzlich über alles Mögliche raten, einschließlich der Tabelle, die Sie für Person verwenden wollten, und der Feldzuordnungen. NHibernate könnte wahrscheinlich gehackt werden, um eine dynamische Bindung basierend auf der Übereinstimmung der Namen oder etwas zu tun, aber die ganze Idee besteht darin, die Zuordnungen von einfachen alten Datenobjekt zu den Datenbankfeldern mit den XML-Dateien zu erstellen.

0

Wenn es gibt nicht einen wirklich guten Grund, nicht die Klasse abzubilden, einfaches Hinzufügen der Zuordnung geben Ihnen die besten Ergebnisse ...

Das heißt, man kann nicht eine benannte Abfrage verwenden, um direkt Ergebnisse zu injizieren in eine nicht zugeordnete Klasse. Sie müssten ihm sagen, welche Spalten in welche Felder oder mit anderen Worten ein Mapping eingefügt werden sollen. ;) Sie können jedoch Skalarwerte aus einer benannten Abfrage zurückgeben, und Sie könnten diese Objektarrays übernehmen und Ihre Sammlung manuell erstellen.

9

Warum Sie nicht verwenden: using Spalte alias als Eigenschaftsnamen

query.SetResultTransformer(Transformers.AliasToBean(typeof(Person)));

Es wird Daten aus jeder Spalte in Ihrer Abfrage in Objekteigenschaften Person einfügen.

2

Wie können Sie eine Abfrage erstellen, die Instanzen eines Typs zurückgibt, der nicht zugeordnet ist?

Ich denke, Michal hat hier einen Punkt, und vielleicht sollten Sie sich Projektionen anschauen. (Zumindest ist das, was ich denke, dass Sie suchen).

Sie erstellen eine Abfrage für einen zugeordneten Typ, und dann können Sie diese Abfrage zu einem "DTO" "projizieren". Um dies zu tun, müssen Sie Ihre Person-Klasse importieren, so dass sie NHibernate bekannt ist, und Sie müssen einen ResultTransformer verwenden.

Etwas wie folgt aus:

ICriteria crit = session.CreateCriteria (typeof(Person)); 

// set some filter criteria 

crit.SetProjection (Projections.ProjectionList() 
        .Add (Property("Name"), "Name") 
        .Add (Property(...) 
        ); 

crit.SetResultTransformer(Transformers.AliasToBean(typeof(PersonView)); 

return crit.List<PersonView>(); 

Aber bedeutet dies immer noch Sie import die Klasse haben werden, so dass NHibernate davon weiß.

+0

Projektionen sind nicht ganz das, wonach ich suche, aber der TupleToPropertyResultTransformer oder der AliasToBean-Transformator erfüllt die Aufgabe. Ich habe keinen Zugriff auf die Klasse, um ihr einen neuen Konstruktor zur Verwendung des AliasToBean-Transformers zu geben, damit ich den TupleToPropertyResultTransformer verwende – lomaxx

Verwandte Themen