Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
NHibernate-三个类之间的三个双向关系给出N+1_Nhibernate_Fluent Nhibernate_Bidirectional Relation - Fatal编程技术网

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

NHibernate-三个类之间的三个双向关系给出N+1,nhibernate,fluent-nhibernate,bidirectional-relation,Nhibernate,Fluent Nhibernate,Bidirectional Relation,我有一个有点复杂的物体模型,形成一个三角形。有一个用户实体,它具有项和分类的集合。项目也有一个分类法。为了方便起见,我希望Item和Taxonomy知道它的所有者,Taxonomy知道它的项(如果有的话)。见图表: 这就形成了三个双向关系。我的问题是,当我像这样在NHibernate中映射它并要求用户使用给定的ID时,我遇到了问题 首先,用户被加载了急切获取的项目。然后,分类法会加载与之连接的急切获取的项。这是预期的,也是映射中定义的。但是现在有N+1个查询来加载与分类法相关的项 这是多余的,因

我有一个有点复杂的物体模型,形成一个三角形。有一个用户实体,它具有项和分类的集合。项目也有一个分类法。为了方便起见,我希望Item和Taxonomy知道它的所有者,Taxonomy知道它的项(如果有的话)。见图表:

这就形成了三个双向关系。我的问题是,当我像这样在NHibernate中映射它并要求用户使用给定的ID时,我遇到了问题

首先,用户被加载了急切获取的项目。然后,分类法会加载与之连接的急切获取的项。这是预期的,也是映射中定义的。但是现在有N+1个查询来加载与分类法相关的项

这是多余的,因为对象图的所有部分都已加载。当我从用户端将我的用户项关系设置为单向时,这个问题就消失了。正如预期的那样,只有两个查询,但我不想删除那个向后的关系。这三种关系都是双向的,有可能实现最佳抓取吗

以下是我的映射部分:

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);

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

我建议您通过查询中的另一条路径执行即时加载

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

我不会在任何其他场景中使用用户。无论如何,结果是相似的。第一个查询连接所有需要的内容,第二个单独提取项目,项目再次出现N+1。测试之前是否从映射中删除了延迟加载规范?好的,我让它在查询和映射版本中运行。无论如何,我很好奇,如果所有的值都应该是已知的,为什么它需要发出单独的查询来加载分类法的项。。。