是否有NHibernate赢得';t返回代理对象

本文关键字:返回 代理 对象 NHibernate 赢得 是否 | 更新日期: 2023-09-27 18:28:45

我正在学习Fluent NHibernate(以及一般的NHibernat)。我使用带有一些覆盖的自动映射,但我认为这对问题不重要(当然,如果我错了,我很乐意更新这个问题)。

给定一个ISession(以及一些假定的变量),我可以通过它们的ID:返回实体

using (var session = SessionFactory.OpenSession())
{
    var user = session.Get<User>(userId);
}

我有限的理解是,NHibernate围绕User映射的实体创建了一个代理,但当我测试它时(基于此):

Assert.That(user is INHibernateProxy, "Not a proxy.");

我的实例似乎不是代理。

是否存在不使用代理的情况我希望能找到"缺失的部分",并祈祷这不是周五下午的大脑衰竭。

是否有NHibernate赢得';t返回代理对象

正如NOtherDev所说,代理用于延迟加载。但即使是Session.Get有时也会返回一个代理。这让我好几次措手不及。如果通过如下指定lazy="true"对表中的任何列使用延迟加载:

<property name="Description" type="StringClob" not-null="false" lazy="true"/>

Session。Get将始终返回此类型的代理,并且无法取消对对象的代理。事实上,代理才是真正的对象。

顺便说一句,禁用延迟加载真的是个糟糕的主意。你可以在这里阅读更多关于这一点的信息:NHibernate很懒,只需要忍受它

有些问题永远不会太老;)在现实生活中,您通常通过访问反向关系的"父"或通过Load()加载对象来获得代理。但是,如果对象以前已经加载到缓存中,那么您将获得第一次访问的类型。所以Load/Get可能同时返回代理或真实实例。

        // if object has been loaded, load will return real instance
        using (var session = CreateSession())
        {
            postByGet = session.Get<Post>(post1Id);
            postByLoad = session.Load<Post>(post1Id);
            Assert.IsFalse(postByGet is INHibernateProxy);
            Assert.IsFalse(postByLoad is INHibernateProxy);
            Assert.IsTrue(object.ReferenceEquals(postByGet, postByLoad));
        }
        // if proxy has been loaded, get will return filled proxy
        using (var session = CreateSession())
        {
            postByLoad = session.Load<Post>(post1Id);
            postByGet = session.Get<Post>(post1Id);
            Assert.IsTrue(postByGet is INHibernateProxy);
            Assert.IsTrue(postByLoad is INHibernateProxy);
            Assert.IsTrue(object.ReferenceEquals(postByGet, postByLoad));
        }

通常代理用于延迟加载。每当你通过Get等获取授权时,你得到的不是代理,而是真实的对象。NHibernate在没有必要的时候不要使用代理。

但是,如果user具有Address,则user.Address is INHibernateProxy将为真(除非针对该关系关闭延迟加载)。

有关NHibernate如何以及何时处理代理的更多信息,请参阅本文。

ISession.Get总是返回null或真实对象。ISession.LoadOTOH可以返回代理(或抛出异常),但代理是另一回事:持久类应该满足一些先决条件(虚拟属性、非密封等)。

相关文章: