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
。 因此,在这种情况下,我们可以加入User
和Group
,并从用户和少数群组中投放很少的属性。 最好的目标是一些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。 使用批量提取
请参阅:
- 带有Fetch的NHibernate QueryOver导致多个sql查询和db命中
- 这是在NHibernate中急切加载子集合的正确方法
- https://stackoverflow.com/questions/18419988/