0

How would I use nHibernate,configured by fluent nhibernate if it makes any difference, to load an entity using natural/alternate key in some cases, rather than the primary key when using the Load method on an ISession.

I still need the functionality to allow me to do both, and in the majority of cases, the entity will be loaded via the PKey, but in some cases (where an external system is involved), I need to select the record using the natural key.

I'd like to keep the performance benefit Load allows, rather than do a query etc.

 // 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);

1 Answer 1

4

AFAIK, it is not possible. As you can see in Ayendes post, there is a query syntax for criteria, the only natural ID in the whole NHibernate API as far as I know. This query translates into a "normal" query, except of the second level cache handling as described in this post.

It would be nice if it wouldn't at least flush the session.

one simple performance enhancement you can do is turning off auto flush before querying by the (immutable!) natural ID:

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

This can make a big difference, but does of course not compete to Load.

The reason why it doesn't exist is most probably the fact the entities in the session are all identified by the id.

If you had it:

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

How could NH determine that the id and the natural id are identifying the same object, without loading them from the database? The whole session cache gets into trouble.

Sign up to request clarification or add additional context in comments.

2 Comments

yea, your last point does makes sense. so, my work around, is to load a mapping data structure of natural key -> pkey at bootstrap time, and use this as a lookup to translate the values. assuming both values are immutable for the lifetime of the app, any issues with this?
Generally this should work. You can add them to the map when the are loaded the first time. You could use a PostLoad event to add keys of any loaded entity. Consider memory consumption of the map and thread safety.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.