NHibernate - 三个类之间的三个双向关系给出N + 1

时间:2011-07-11 12:03:22

标签: nhibernate fluent-nhibernate bidirectional-relation

我有一个复杂的对象模型,形成一个三角形。 User个实体包含ItemsTaxonomies的集合。 Item也有分类法。为方便起见,我希望ItemTaxonomy知道其所有者,并Taxonomy知道其Item,如果有的话。见图:

diagram

所以这会产生三个双向关系。我的问题是当我在NHibernate中映射它并要求具有给定ID的用户时,我遇到Select N+1问题。

首先,User加载了急切获取的Items。然后Taxonomies加载了与其连接的热切提取的Item。这与预期和映射中定义的一样。但现在有N + 1个查询要加载与Items相关的Taxonomies

queries

这是多余的,因为对象图的所有部分都已加载。当我从User-Item方面单向User时,问题就消失了(正如预期的那样,只有2个查询),但我不想删除那个向后关系。 是否可以使用双向的所有三种关系进行最佳提取?

以下是我的映射部分:

public class UserOverride : IAutoMappingOverride<User>
{
    public void Override(AutoMapping<User> mapping)
    {
        mapping.HasMany(x => x.Items).Inverse()
            .Not.LazyLoad().Fetch.Join();
        mapping.HasMany(x => x.Taxonomies).Inverse()
            .LazyLoad().Fetch.Select();
    }
}

public class ItemOverride : IAutoMappingOverride<Item>
{
    public void Override(AutoMapping<Item> mapping)
    {
        mapping.References(x => x.Taxonomy); // many-to-one
    }
}

public class TaxonomyOverride : IAutoMappingOverride<Taxonomy>
{
    public void Override(AutoMapping<Taxonomy> mapping)
    {
        mapping.HasOne(x => x.Item).PropertyRef(x => x.Taxonomy)
            .Not.LazyLoad().Fetch.Join();
    }
}

我以最简单的方式查询我的数据库:

var user = session.Get<User>(1);

1 个答案:

答案 0 :(得分:1)

因为映射会影响所有查询,所以我喜欢遵循这样的规则,即只有在没有其他实体的情况下实体永远不会有用的情况下,映射才应该更改为急切加载。在您的情况下,如果您只是想要用户,并且不太关心项目和分类法记录,那么您将进行额外的数据库工作,没有任何好处。

我建议您在查询中通过其他路线执行急切加载。

Session.QueryOver<User>().Where(u => u.Id == 1)
    .join.QueryOver<Items>(u => u.Items)
    .Join.QueryOver<Taxonomy>(i => i.Taxonomy)
    .TransformUsing(Trasnformers.DistinctRootEntity);