nhibernate 可以在没有代理的情况下进行延迟加载吗?

Posted

技术标签:

【中文标题】nhibernate 可以在没有代理的情况下进行延迟加载吗?【英文标题】:nhibernate can you lazyload without proxies? 【发布时间】:2009-12-28 17:46:06 【问题描述】:

我已经开始深入研究 Nhibernate,虽然有很多我喜欢的东西,但有一点我不喜欢:“生成代理”/延迟加载机制。在访问可能触发延迟加载的属性之前,我必须维护对 ISession 的某种引用并确保实体与会话相关联,这种想法在我的视图模型中比我欣赏的要复杂一些。在我使用的最后一个 ORM 映射器中,我们采用了一种不同的延迟加载方法,它可以完全忽略会话问题,但代价是更少的 POCO 实体。我基本上想用 nhibernate 做同样的事情,语法类似于:

public class Order

    // this will introduced through the ctor using for ex an interceptor and Castle Windsor
    private IOrmService ormService;
    List<OrderLine> details = new List<OrderLine>();

    public IEnumerable<OrderLine> Details
    
        get
        
            ormService.LazyLoad(this, o => o.Details);
            return this.details;
        
    

如果集合已经加载,ormService 将简单地忽略来自实体的延迟加载请求(更不用说状态管理问题 :-))。我查看了 NHibernateUtils 类,它有一些 Initialized 和 Initialize-collection 方法,但它们假设您使用的是代理。基本上,我需要一种告诉 nhibernate 的方法,例如:“嘿,使用我给你的这个会话填充这个属性”。状态管理等可以在外部处理。在 Nhibernate 中是否支持这样做?

【问题讨论】:

【参考方案1】:

我对你的问题有点困惑。我觉得遵循 Hibernate 最佳实践就足够了,不需要重新发明已经存在的东西。这里有几个cmets。

我必须保持一些想法 有点参考 ISession 和 确保实体关联 在访问之前与会话 可能触发的属性 延迟加载更复杂一些 我的视图模型比我欣赏的要好

如果您遵循open session in view 模式,这将变得非常容易。

这里的想法是 ormService 将简单地忽略延迟加载 来自实体的请求,如果 集合已加载

惰性代理已经这样做了。

基本上,我需要一种表达方式 像休眠一样:“嘿, 使用此填充此属性 我给你的会话”。

当您将对象分离/附加到会话时所做的事情。惰性项将根据对象附加到的会话加载。

【讨论】:

【参考方案2】:

答案是否定的,没有代理就不能进行延迟加载。代理需要由 NHibernate 创建,或者您实现的任何类型的类或模式都将产生相同的最终结果,除非您只是移动了代理的生成位置/方式。

为了使延迟加载工作,它本质上需要 ISession 否则将无法连接到数据库以检索所需的值。

NH 实现其代理模式的方式可能是您将实现的最好的方式,至少在 .NET 4.0 之前,新的动态词可能会稍微改变一下。

【讨论】:

以上是关于nhibernate 可以在没有代理的情况下进行延迟加载吗?的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate 2.1 代理工厂选项 - 有啥区别以及选择哪个?

NHibernate.LazyInitializationException: Initializing[] - 无法初始化代理 - 没有会话

没有外键的NHibernate映射集合

NHibernate 保存非持久化实体,同时保持现有 ID

在 Nhibernate 中分离和附加代理

在不加入的情况下运行 NHibernate 查询