如何在NHibernate中没有重复的情况下加载加载关联?

The*_*ght 4 nhibernate orm future cartesian-product eager-loading

我需要加载一个包含很多孩子和孩子孩子的非常大的物品清单.什么是最好的方法?

我正在使用Oracle 11g数据库,我编写了以下方法,但它产生了笛卡尔积(重复结果):

 public IList<ARNomination> GetByEventId(long eventId)
        {
            var session = this._sessionFactory.Session;

            var nominationQuery = session.Query<ARNomination>().Where(n => n.Event.Id == eventId);

            using (var trans = session.Transaction)
            {
                trans.Begin();

                // this will load the Contacts in one statement
                nominationQuery
                    .FetchMany(n => n.Contacts)
                    .ToFuture();

                // this will load the CustomAttributes in one statement
                nominationQuery
                    .FetchMany(n => n.CustomAttributes)
                    .ToFuture();

                // this will load the nominations but joins those two tables in one statement which results in cartesian product
                nominationQuery
                    .FetchMany(n => n.CustomAttributes)
                    .FetchMany(n => n.Contacts)
                    .ToFuture();

                trans.Commit();
            }

            return nominationQuery.ToList();
        }
Run Code Online (Sandbox Code Playgroud)

Rad*_*ler 11

获取集合是一项困难的操作.它有很多副作用(正如你所知,当有更多的集合时).但即使提取了一个集合,我们也会加载许多重复的行.

通常,对于集合加载,我建议使用批处理.这将执行更多SQL查询...但不是那么多,更重要的是,您可以在根列表上执行分页ARNomination.

见:19.1.5.使用批量提取,您可以找到更多详细信息.

您必须使用属性标记集合和/或实体batch-szie="25".

XML:

<bag name="Contacts" ... batch-size="25">
...
Run Code Online (Sandbox Code Playgroud)

流利:

HasMany(x => x.Contacts)
  ...
  .BatchSize(25)
Run Code Online (Sandbox Code Playgroud)

请在这里查看一些参数: