【问题标题】:NHibernate always hydrates many-to-oneNHibernate 总是多对一的保湿
【发布时间】:2015-03-16 19:17:50
【问题描述】:

我在使用 NHibernate 时遇到了一些奇怪的事情。我打开了一个不是我写的代码库,而写的那个已经不在了。所以我想我正在寻找的更多的是调试技巧。

我正在使用 NHIbernate 3.4 Linq 提供程序来查询与另一个实体具有多对一关系的实体。

我看到的是,即使我从未访问过代表多对一关系的属性,它也始终是水合的。通过 NHibernate 分析器查看查询,我可以看到该属性似乎是延迟加载的。使用我的调试器设置断点,我可以看到该属性从未被访问过。

使用 NHibernate 分析器时,我可以看到它在我加载父实体列表时发生,但不是在同一个查询中。

我不知道为什么会发生这种情况,但它会导致 N+1 问题。

实体在 hbm.xml 文件中定义。

所以我要的是输入我应该开始挖掘的地方。我觉得我已经尝试了我能想到的一切。

【问题讨论】:

    标签: c# linq nhibernate many-to-one


    【解决方案1】:

    我几乎可以肯定地说,问题不在于 NHibernate,而在于使用方面(我们都同意我的说法)

    那么,我们应该(隐式或显式)作为起点的是惰性设置:

    // class level
    // by default lazy is turned on
    <class name="Entity" ... lazy="true" ... >
       ...
    
    // reference many-to-one level, also by default lazy
    <many-to-one name="Entity" lazy="proxy" ... />
    

    为了避免 N+1,我们应该确保使用带有 batch-size 设置的批量获取,see more here

    // class/entity level
    // ATTENTION - this is not implicit, we have to define that
    <class name="Entity" ... lazy="true" ... batch-size="25" >
      ...
    
    // collection level
    // ATTENTION - this is not implicit, we have to define that
    <bag name="Entities" ... batch-size="25">
    ...
    

    有了它,现在 NHibernate 本身将永远不会加载超出需要的内容。那么,当需要加载参考时,典型的用例可能是什么?

    覆盖时:

    public override bool Equals(object obj)
    {
    }
    public override int GetHashCode()
    {
    }
    

    这些方法应该(有时 - 对于复合 ID,甚至必须)被覆盖,以提供业务唯一键。检查任何引用的值是否未用于此类比较(例如,对于某些 OtherEntity,Country 和 Office 的组合是唯一的)

    最后但并非最不重要的,您的调试器可能存在问题。调试器实际上是在影响加载,因为每当我们在调试窗口中观察到任何东西时……我们都会强制 NHibernate 加载惰性的东西。

    令人惊讶的是,这是“强制”加载的最常见来源。所以,清除你的观察者......

    最后建议 - 创建 单元测试 以仅加载根实体。最后清除会话。观察(使用探查器)是否有一些 DB 命中。然后您可以更轻松地检查原因...

    【讨论】:

    • 我几乎不敢大声说出我的发现。正如你(和我)所预料的那样,这不在 NHibernate 上。
    • 我找到了一个扩展NHibernate.EmptyInterceptor的类,并且重写了OnLoad方法。在该方法中,每个引用属性都被触摸,以便检查某些内容。因此导致对象图中每个引用类型的水合。
    • 很高兴看到你成功了。享受 NHibernate,很棒的工具 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多