当使用连接时,使用nhibernate停止重复的子节点或n+1

本文关键字:子节点 n+1 nhibernate 连接 使用 | 更新日期: 2023-09-27 18:05:30

我有一个父类,它有许多具有映射的子类:

HasMany(x => x.Children).KeyColumn("ParentId");

存储库的功能如下:

Parent parent = null;
Child child = null;
var query = Session.QueryOver(() => parent )
.JoinAlias(() => parent.Children, () => child , JoinType.InnerJoin)
.TransformUsing(Transformers.DistinctRootEntity).Skip(skip).Take(25).List();

它工作得很好,除了它触发多个调用来选择子节点,当它们从父节点被访问时。

我不想要多个DB命中,所以我改变代码有映射为:

 HasMany(x => x.Children).KeyColumn("ParentId").Fetch.Join();

并完全删除了连接别名,除了父节点在select中多次出现之外,这同样可以正常工作。例如,从生成的选择查询返回的sql行如下:

ParentId | ChildId
123      |1
123      |1
124      |2
125      |1

但是它得到的输出对象为Parent, id 123出现两次(这是正确的),但都有四个id为1的子(这是错误的,它只有一个子)

我的问题是,你可以有一个HasMany没有n+1发生?

当使用连接时,使用nhibernate停止重复的子节点或n+1

取下Fetch.Join并使用批处理,从我的记忆中您使用BatchSize

HasMany(x => x.Children).KeyColumn("ParentId").BatchSize(25);

正如你所发现的,如果你使用分页,fetch join是没有用的,因为你会得到一个笛卡尔积(重复)