NHibernate的总是滋润多到一个(NHibernate always hydrates man

2019-10-22 07:10发布

我使用NHibernate时遇到一些奇怪的。 我已经打开了,我没有写代码库,以及谁做了一个不在这里了。 所以,我想我在找的是调试比什么都重要提示。

我使用NHibernate 3.4 LINQ提供程序,查询实体,具有多到一个关系到另一个实体。

我看到的是,尽管我从来没有访问表示多到一个关系它总是水化财产。 通过观察通过NHibernate的探查的疑问,我可以看到属性似乎是懒加载。 我的调试器中设置断点,我可以看到该属性从来没有访问。

当使用NHibernate的探查,我可以看到,当我加载父实体列表它发生,但不是在同一个查询。

我不知道为什么会这样,但它会导致N + 1点的问题。

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

所以,我所要求的是输入到哪里我应该开始挖掘。 我觉得我已经试过,我能想到的一切都已经。

Answer 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设置, 多看这里

// 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()
{
}

这些方法应该是(somtimes - 复合-ID,甚至必须)overrided,提供业务唯一的密钥。 检查中,任何参考价值的不用于这样的比较(国家如组合和Office是唯一某些OtherEntity)

最后但并非最不重要的 ,有可能是有问题你的调试器。 调试器实际上是在实现装载,因为每当我们在调试窗口中看到什么...我们强迫的NHibernate加载懒的东西。

这是令人惊讶的最经常“被迫”装载的来源。 所以,清除观察家...

最后的建议-创建单元测试来加载只是根实体。 清底会话。 观察(使用Profiler),如果有一些DB命中。 您可以更轻松地再检查是什么原因?



文章来源: NHibernate always hydrates many-to-one