NHibernate中的项目集合

我可以在NHibernate中进行项目收集吗? 例如:

User { UserGuid, IList UserGroups, } User userEntity = null; _session .StatefulSession.QueryOver(() => userEntity) .SelectList(list => list .Select(x => x.UserGuid).WithAlias(() => userEntity.UserGuid) //How can I project group collection here? .Select(x => x.Groups).WithAlias(() => userEntity.Groups) ) .TransformUsing(Transformers.AliasToBean()) .List(); 

我们必须将投影作为单个SELECT子句。 我们可以在数据库端用它做什么,我们可以模仿QueryOver 。 因此,在这种情况下,我们可以加入UserGroup ,并从用户和少数群组中投放很少的属性。 最好的目标是一些DTO ……

语法可能是这样的:

 ResultDTO resultDTO = null; // the target to be returned Group groupEntity = null; User userEntity = null; _session.StatefulSession .QueryOver(() => userEntity) .JoinAlias(() => userEntity.Groups, () => groupEntity) .SelectList(list => list .Select(x => x.UserGuid).WithAlias(() => resultDTO.UserGuid) // more about User - targeting the ResultDTO ... // almost the same for Group properties .Select(x => groupEntity.Name).WithAlias(() => resultDTO.GroupName) .. ) .TransformUsing(Transformers.AliasToBean()) .List(); 

但是存在一些问题,实际上实际上不允许这种方法。 我们将达到Cartesian product ,因为用户的每一行都会乘以它所拥有的多个组。

 Row 1 - User A - Group A Row 2 - User A - Group B // two rows for a user A Row 3 - User B - Group B Row 4 - User B - Group C 

解决它的一种方法是跳过SelectList() (不使用投影)并要求NHiberante使用不同的转换:

 _session.StatefulSession .QueryOver(() => userEntity) .JoinAlias(() => userEntity.Groups, () => groupEntity) .TransformUsing(Transformers.DistinctRootEntity) .List(); 

人们会说,很好,但又错了。 没有有效的分页是可能的,因为每个用户的更多行的影响仍然存在。 所以,如果我们说Take(2) ,我们只会得到用户A. 事实上隐藏的原因是,缩小是在内存中,在.NET /应用程序层上进行的,而不是在DB中

建议:不要在一对多关系中使用任何联接。 使用分离的查询以及强大的NHibernatefunction: 19.1.5。 使用批量提取

请参阅: