NHibernate有时不会返回代理对象吗?

问题描述 投票:2回答:4

我正在学习Fluent NHibernate(并且扩展为NHibernate)。我正在使用带有某些替代的自动映射,但是我认为这对问题不重要(当然,如果我在这里错了,我会很乐意更新问题)。

给出ISession(以及更多假定的变量),我可以通过其ID返回实体:

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

我有限的理解是NHibernate围绕User映射实体创建了一个代理,但是当我对其进行测试(based on this)时:

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

似乎我的实例不是代理。

有没有使用代理的情况吗?我希望得到“缺失的部分”,并祈祷这不是星期五下午的脑力衰竭。

c# nhibernate fluent-nhibernate
4个回答
3
投票

通常,代理用于延迟加载。每当您通过Get等获取权限时,您并没有获得代理,而是获得了真实的对象。 NHibernate在不需要时不使用代理。

但是如果user具有Address,则user.Address is INHibernateProxy将为true(除非为此关系关闭了延迟加载)。>>

有关NHibernate如何以及何时处理代理的更多信息,请参见this article。>

ISession.Get总是返回null或真实对象。ISession.LoadOTOH can

返回一个代理(或引发异常),但是代理完全是另外一回事:您的持久性类应满足一些先决条件(虚拟属性,未密封等)。

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

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

Session.Get将始终返回此类型的代理,并且没有办法取消代理对象。实际上,代理是真实的对象。

顺便说一句,禁用延迟加载确实是一个非常糟糕的主意。您可以在这里阅读更多有关此的信息:NHibernate is lazy, just live with it

有些问题永远不会太老;)在现实生活中,通常通过访问逆关系的“父级”或通过Load()加载对象来获得代理。但是,如果该对象之前已经被加载到缓存中,则将获得第一次访问的类型。因此,加载/获取可能都返回代理或真实实例。

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

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

3
投票

ISession.Get总是返回null或真实对象。ISession.LoadOTOH can


0
投票

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


0
投票

有些问题永远不会太老;)在现实生活中,通常通过访问逆关系的“父级”或通过Load()加载对象来获得代理。但是,如果该对象之前已经被加载到缓存中,则将获得第一次访问的类型。因此,加载/获取可能都返回代理或真实实例。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.