我使用NHibernate时遇到一些奇怪的。 我已经打开了,我没有写代码库,以及谁做了一个不在这里了。 所以,我想我在找的是调试比什么都重要提示。
我使用NHibernate 3.4 LINQ提供程序,查询实体,具有多到一个关系到另一个实体。
我看到的是,尽管我从来没有访问表示多到一个关系它总是水化财产。 通过观察通过NHibernate的探查的疑问,我可以看到属性似乎是懒加载。 我的调试器中设置断点,我可以看到该属性从来没有访问。
当使用NHibernate的探查,我可以看到,当我加载父实体列表它发生,但不是在同一个查询。
我不知道为什么会这样,但它会导致N + 1点的问题。
该实体在hbm.xml文件中定义的。
所以,我所要求的是输入到哪里我应该开始挖掘。 我觉得我已经试过,我能想到的一切都已经。
我几乎肯定地说,这个问题是不是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命中。 您可以更轻松地再检查是什么原因?