2012-04-05 6 views
0

Wie würde ich nHibernate verwenden, konfiguriert durch fließende nhibernate, wenn es einen Unterschied macht, eine Entität mit natürlichen/alternativen Schlüssel in einigen Fällen, anstatt den Primärschlüssel bei Verwendung der Load Methode laden auf einer ISession.nHibernate Proxy Load mit Natural Key

Ich brauche immer noch die Funktionalität, um mir beides zu ermöglichen, und in den meisten Fällen wird die Entity über den PKey geladen, aber in einigen Fällen (wo ein externes System involviert ist), muss ich das auswählen Aufzeichnung mit dem natürlichen Schlüssel.

Ich mag würde den Leistungsvorteil Load erlaubt zu halten, anstatt zu tun, eine Abfrage usw.

// Current 
int countryID = 1; // from normal input source 

Address a = new Address(); 
a.Country = session.Load<Country>(countryID); 

session.SaveOrUpdate(a); 

// Required 
string countryCode = "usa"; // from external input source 

Address a2 = new Address(); 
a2.Country = session.LoadViaNatualKeySomehow<Country>(c=> c.Code, countryCode); // :) 

session.SaveOrUpdate(a2); 

Antwort

4

AFAIK ist es nicht möglich. Wie Sie in Ayendes post sehen können, gibt es eine Abfragesyntax für Kriterien, die einzige natürliche ID in der gesamten NHibernate API, soweit ich weiß. Diese Abfrage wird in eine "normale" Abfrage übersetzt, mit Ausnahme der Cache-Behandlung auf der zweiten Ebene, wie in diesem Beitrag beschrieben.

Es wäre schön, wenn es die Sitzung nicht mindestens flush würde.

eine einfache Leistungssteigerung Sie tun können, ist das Ausschalten automatisch bündig, bevor sie vom (unveränderlich!) Natürliche ID abfragen:

session.FlushMode = FlushMode.Never; 
session.CreateQuery(...by natural id ...); 
session.FlushMode = FlushMode.Auto; 

Dies kann einen großen Unterschied machen, aber konkurriert natürlich nicht zu laden.

Der Grund, warum es nicht existiert, ist höchstwahrscheinlich die Tatsache, dass die Entitäten in der Sitzung alle durch die ID identifiziert werden.

Wenn Sie es hatte:

var entity1 = session.Load<Entit>(id); 
// does not exist 
var entity2 = session.LoadByNaturalKey(natural id); 

Wie konnte NH bestimmen, dass die ID und die natürliche id das gleiche Objekt identifizieren, ohne sie aus der Datenbank zu laden? Der gesamte Sitzungs-Cache gerät in Schwierigkeiten.

+0

ja, dein letzter Punkt macht Sinn. Also, meine Arbeit herum, ist es, eine Mapping-Datenstruktur des natürlichen Schlüssels -> pkey während der Bootstrap-Zeit zu laden und diese als eine Suche zu verwenden, um die Werte zu übersetzen. Angenommen beide Werte sind für die Lebensdauer der App unveränderbar, irgendwelche Probleme damit? – jasper

+0

Normalerweise sollte das funktionieren. Sie können sie der Karte hinzufügen, wenn sie das erste Mal geladen werden. Sie können ein PostLoad-Ereignis verwenden, um Schlüssel einer geladenen Entität hinzuzufügen. Berücksichtigen Sie den Speicherverbrauch der Karte und die Thread-Sicherheit. –