NHibernate - 访问关联对象的ID而不延迟加载整个对象

Yon*_*rni 7 nhibernate lazy-loading associations

我有两个相关的业务对象--A和B.关联是(A-> B)多对一,B.Id是A中的外键(所以A在DB中有A.B_id).

我正在使用lazy = true并且解决了我的大多数问题,但是在A的ToString中我想打印ABId,我应该没有进一步访问数据库.但是访问AB会激活代理,因为这不是在打开会话的上下文中,所以会抛出异常.

一个简单但丑陋的解决方案是拥有A.B_id属性.但这是我们首先想要避免的东西的一部分.任何"有机"的方式来做到这一点?:) 谢谢!


更新:刚刚阅读有关缓存和Session.Get与Session.Load的内容.如果对象不存在(Session.Load),那么只有新的那个抛出异常,而另一个返回一个空对象(Session.Get).在阅读了这里的缓存之后,很明显Session.Load会返回一个代理到该对象,只有在访问ID以外的属性时才会懒惰地抓取它,这非常类似于我需要的关联!现在我添加了单独的对象ID(将B_Id添加到A中,因此我可以将其作为A.B_Id访问而不是使用ABId)

Qua*_*uan 6

如果您使用的是NHibernate 3.2或更高版本,则可以使用以下代码获取关联对象的id,而无需另外往返数据库以加载整个对象:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)


tol*_*sm7 5

出于完全相同的原因,我为所有多对一关系使用了显式 AB-ID 属性。我不认为这是一个快速而肮脏的解决方案,因为它为这个问题提供了解决方案,而且保存更新区域也有很大的灵活性,即我不需要从数据库中获取 B 对象只是为了将它分配给 A为了在查询字符串或其他地方有 B_ID 时创建关联。

我的映射文件通常如下所示:

<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" />
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,必须只读 2 个属性之一,以避免在发生插入或更新时 NHibernate 将此列发送 2 次到数据库。以上使多对一成为只读(通过使用 insert="false" update="false" 属性),但如果您愿意,您可以改为将 CreatorID 属性设为只读。

只有多对一,您的实体类 A 中没有属性来保存 B.ID 值。获取它的唯一方法是访问将触发代理的 B 对象,它将向数据库发出查询(如果它尚未加载到会话中)。

我很高兴听到任何其他提供解决方案并提供相同灵活性的选项。