我正在使用Nhibernate查询,我必须在其中执行一些复杂的查询加入别名以急切加载我的根实体的子项。加载时,我想过滤许多属性返回的根实体结果,包括子项上的一些属性。
我使用joinaliases工作得很好,但我难倒的地方是当根据实体以外的属性进行排序时,将结果返回到根实体的顶部“X”实例ID 即可。由于我抓住了孩子,SQL返回了许多重复的行。如果我尝试使用.Take过滤结果数,则在NHibernate将结果集折叠到不同的根实体之前执行take。这里是我的域模型的参考。
public class Project{
public int Id {get;set;}
public double Value {get;set;}
public IList<ProjectRole> Team {get;set;}
}
public class ProjectRole{
public User User {get;set;}
public Role Role {get;set;}
}
public class User{
public string LoginName {get;set;}
}
所以我试图抓住项目团队中具有给定LoginName的用户的所有项目。然后我想按项目的价值排序。我想尽可能高效地做到这一点,没有选择n + 1等。
此社区推荐什么?
其他信息: 作为权宜之计,我目前正在返回所有结果,然后在内存中占据前十名,但我不希望这是永久性的,因为查询可以返回接近10,0000项,我只想顶7左右。如果我直接编写SQL,我会做这样的事情。
SELECT *
FROM Projects as p1
INNER JOIN (
SELECT distinct TOP (7)
topProjects.PGISourceItem_id as topsId,
topProjects.Value as topsValue
FROM Projects topProjects
left outer join ProjectRoles roles on topProjects.Id=roles.Project_id
left outer join PGUsers users on roles.User_id=users.Id
WHERE
(users.LoginName like 'DEV\APPROVER' or this_0_1_.IsPrivate = 0)
ORDER BY topProjects.Value desc
) as p2 on p1.Id = p2.topsId
但我无法弄清楚如何使用NHibernate来做到这一点。我可以创建的唯一子查询是WHERE EXISTS或WHERE IN。因为我正在进行ORDER BY Value,所以我不能使用WHERE IN,因为我的select会返回多个属性。
答案 0 :(得分:0)
如果用户拥有1k以下的项目,这可能会有效
var subquery = QueryOver.Of<User>()
.Where(...)
.JoinAlias(x => x.Projects, () => proj)
.Select(Projections.Distinct(Projections.Property(() => proj.Id)));
session.QueryOver<Foo>()
.WithSubquery.WhereProperty(x => x.Id).In(subquery)
.Fetch(p => p.Collection)
.OrderBy(x => x.Value)
.Take(5)
.List();