【问题标题】:NHibernate - three bidirectional relations between three classes gives N+1NHibernate - 三个类之间的三个双向关系给出 N+1
【发布时间】:2011-07-11 12:03:21
【问题描述】:

我的对象模型有点复杂,形成了一个三角形。有一个 User 实体集合了 ItemsTaxonomiesItem 也有分类。为了方便起见,我想让ItemTaxonomy 知道它的所有者,Taxonomy 知道它的Item,如果有的话。见图表:

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

首先,User 加载了急切获取的Items。然后Taxonomies 加载了急切获取的Item 连接到它。这是预期的并且在映射中定义。但是现在有 N+1 个查询要加载与Taxonomies 相关的Items

这是多余的,因为对象图的所有部分都已加载。当我从User 一侧使我的User-Item 关系单向时,这个问题就消失了(正如预期的那样,只有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);

【问题讨论】:

    标签: nhibernate fluent-nhibernate bidirectional-relation


    【解决方案1】:

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

    我建议您通过查询中的另一条路线执行预先加载。

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

    【讨论】:

    • 我不会在任何其他情况下使用User。无论如何,结果是相似的。第一个查询加入所有需要的内容,第二个查询分别拉出ItemsItems 再次出现 N+1。
    • 您是否在测试之前从映射中删除了延迟加载规范?
    • 好的,我让它在查询和映射版本中运行。无论如何,我很好奇为什么它需要发出单独的查询来加载TaxonomyItems,如果所有的值都应该是已知的......
    猜你喜欢
    • 1970-01-01
    • 2017-07-18
    • 2012-07-11
    • 1970-01-01
    • 2013-07-01
    • 2019-08-26
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多