NHibernate - access the ID of an associated object without lazy loading the whole object

前端 未结 3 1329
北恋
北恋 2020-12-16 05:04

I have two associated business objects - A and B. the association is (A->B)many-to-one, with B.Id a foreign key in A (so A has A.B_id in the DB).

I\'m using lazy=tru

相关标签:
3条回答
  • 2020-12-16 05:22

    If you are using NHibernate 3.2 or later, you could use the following code to get the id of associated object without another roundtrip to database to load the whole 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;
        }
    }
    
    0 讨论(0)
  • 2020-12-16 05:28

    For the exact same reason I have used explicit A.B-ID properties for all my many-to-one relationships. I do not see this as a quick and dirty solution as it provides a solution to this problem and also lot of flexibility is the saving-updating area i.e. I do not need to fetch from the database the B object just to assign it to A in order to create the association when I have the B_ID in a query string or somewhere else.

    My mapping files useually look like this:

    <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 2 properties has to be read only to avoid having NHibernate sending 2 times this column to the database when inserts or updatas are happening. The above makes as read only (by using the insert="false" update="false" attributes) the many-to-one but you can instead have as read only the CreatorID property if you like.

    Having only the many-to-one you do not have a property in your entity class A to hold the B.ID value. The only way to get it is by accessing the B object which will trigger the proxy and it will fire a query to the database (if it is not loaded in the session already).

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

    0 讨论(0)
  • 2020-12-16 05:30

    You can use GetIdentifier method of Nhibernate session :

    session.GetIdentifier(obj);
    
    0 讨论(0)
提交回复
热议问题