NHibernate - access the identifier of the associated object without lazily loading the entire object

I have two related business objects - A and B. A many-to-one association (A-> B), with B.Id the foreign key in (therefore A has A.B_id in the database).

I use lazy = true and solves most of my problems, however in ToString I want to print also ABId, which I should have without further trips to the database. but access to the AB activates the proxy server, and since this does not apply to an open session, it throws an exception.

one simple but ugly solution is to have the A.B_id property. but that part of the thing that we tried to avoid in the first place. any "organic" way to do this? :) thanks!


UPDATE: just read about caching and Session.Get vs. Session.Load. before I'm just a beginner, an exception is thrown if the object does not exist (Session.Load) and the other returns a null object (Session.Get). after reading about caching here , it is clear that Session.Load returns the proxy server to the object and only lazily retrieves it when the property is different from the Access Identifier, which is very similar to what I need from associations! at the moment I added separate object identifiers (B_Id was added to A, so I can access it as A.B_Id instead of using ABId)

+6
nhibernate associations lazy-loading
source share
3 answers

For the same reason, I used explicit AB-ID properties for all my many-to-one relationships. I do not see this as a quick and dirty solution, since it provides a solution to this problem, and flexibility is the area where updates are kept, that is, I do not need to extract object B from the database just to assign it A to create a connection, when I have a B_ID in the query string or somewhere else.

My mapping files are as follows:

<property name="CreatorID" column="CreatorID" type="Int32" not-null="true" /> <many-to-one name="Creator" column="CreatorID" class="SystemUser" insert="false" update="false" cascade="none" /> 

As you can see, one of the two properties should only be read to prevent NHibernate from sending this column 2 times to the database during insertions or updates. The above does read only (using the attributes insert = "false" update = "false") is ambiguous, but you can instead use the CreatorID property only if you want.

With only many-to-one, you do not have a property in the entity class A to store the value B.ID. The only way to get this is to access object B, which the proxy server will call, and it will start a database query (if it is not already loaded into the session).

I will be glad to hear any other option that provides a solution and offers the same flexibility.

+3
source share

If you are using NHibernate 3.2 or later, you can use the following code to get the identifier of the associated object without another return to the database to load the entire object:

 using NHibernate.Proxy; ... object id = null; if (obj.IsProxy()) // obj is the object you want to get its identifier. { var proxy = obj as INHibernateProxy; if (proxy != null) { var li = proxy.HibernateLazyInitializer; if (li != null) id = li.Identifier; } } 
+5
source share

You can use the GetIdentifier method of a Nhibernate session:

 session.GetIdentifier(obj); 
+1
source share

All Articles