左连接、非重复和使用 QueryOver 进行分页

发布于 2024-12-21 21:18:23 字数 1257 浏览 1 评论 0原文

我有这样的问题,这似乎很常见,但事实上,SO 和谷歌的解决方案都不适合我。

让我们考虑这样的情况(与我的非常相似):

    public class User
    {
     public int Id;
     public string Name;
     //30 other fields;
     public IList<Role> Roles;
    }

    public class Role
    {
     public int RoleNumber;
     public int UserId;
    }

1 用户可以拥有 0-多个角色。

我想在网格视图上显示用户列表及其字段和附加“角色”列,该列将显示他的所有角色编号(使用转发器)。为了实现这一点,我需要获取用户及其角色的不同列表。

是否可以使用 QueryOver 创建此类查询?互联网上的所有解决方案都说我应该创建将 Ids 的子查询,然后创建第二个查询,它将返回子查询中 Id 的用户。它可以工作并返回不同的列表,但没有角色,因此 NH 为每个用户生成额外的选择来获取丢失的信息。

我的查询:

Role roles = null;
User users = null;
IQueryOver<User,User> userQuery = ... 
IQueryOver<User,User> distQuery = ...
distQuery.JoinAlias(f=> f.Roles, () => Roles, JoinType.LeftOuterJoin)
         .Select(Projections.Distinct(Projections.Id()));

userQuery.WithSubquery.WhereProperty(g => g.Id).In<User>((QueryOver<User>)    distQuery) //and other joins, wheres etc.

返回没有角色的非重复列表

如果我将第二个连接添加到角色,它将返回包含角色和重复项的列表

如果我将第二个连接添加到角色并使用

TransformUsing(new DistinctRootEntityResultTransformer())

它将返回包含用户及其角色的非重复列表,但分页将不起作用并且 RowCount () 将返回错误的数字。

有什么想法我能做什么吗?

I have such problem which seems to be common, but in fact none of solutions from SO and google work for me.

Lets consider such situation (very similiar to mine):

    public class User
    {
     public int Id;
     public string Name;
     //30 other fields;
     public IList<Role> Roles;
    }

    public class Role
    {
     public int RoleNumber;
     public int UserId;
    }

1 User can have 0-many roles.

I want to display on gridview list of users with its fields and additional "Roles" column which will display all his RoleNumbers (using repeater). To obtain that, I need to get distincted list of Users with its Roles.

Is it possible to create such query with QueryOver ? All the solutions from internet say that I should create subquery which will Ids and then second query which will return Users which Id is in subquery. It works and returns me distincted list, but without Roles, so NH generates additional select for each user to get that missing information.

My Query:

Role roles = null;
User users = null;
IQueryOver<User,User> userQuery = ... 
IQueryOver<User,User> distQuery = ...
distQuery.JoinAlias(f=> f.Roles, () => Roles, JoinType.LeftOuterJoin)
         .Select(Projections.Distinct(Projections.Id()));

userQuery.WithSubquery.WhereProperty(g => g.Id).In<User>((QueryOver<User>)    distQuery) //and other joins, wheres etc.

returnes distincted list without Roles

If I add 2nd Join to Roles it will return list with Roles and duplicates

If I add 2nd Join to Roles and use

TransformUsing(new DistinctRootEntityResultTransformer())

It will return distincted list with Users and it roles but paging won't work and RowCount() will return incorrect number.

Any ideas what can I do ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧人九事 2024-12-28 21:18:23

基本上 NHibernate 目前不支持您所要求的。您无法预先加载UsersRoles 并保持分页检查。

我首先会获取分页的用户列表(例如 25),然后在需要时延迟加载角色。

Session.QueryOver<User>().Skip(x).Take(25);

并将映射文件更改为:-

<bag class="Role" Name="Roles" batch-size='25' ...>
...
</bag>

这将发送一个查询来检索分页的用户列表,然后发出第二个查询来获取用户的所有角色。这是迄今为止最高效的方式。

Basically what you are asking for is not currently supported with NHibernate. You cannot eager load Users and Roles and keep pagination in check.

I would first get a paged list of users (e.g. 25) then lazy load the roles as and when you need them.

Session.QueryOver<User>().Skip(x).Take(25);

and change your mapping file to:-

<bag class="Role" Name="Roles" batch-size='25' ...>
...
</bag>

This would send one query to retrieve a list of paged Users then issue a second query to get all roles for the users. This is by far the most performant way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文