1

我正在使用一个 Nhibernate 查询,我必须在其中执行一些复杂的查询连接别名来急切地加载我的根实体的子实体。加载时,我想过滤一些属性返回的根实体结果,包括一些在子级上的。

我已经使用连接别名让这一切正常工作,但我很难过的是过滤返回到根实体的顶部“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;}
}

因此,我试图获取具有给定登录名的用户在项目团队中的所有项目。然后我想按项目的价值排序。我想尽可能有效地做到这一点,而无需选择 n+1 等。

这个社区有什么推荐?

附加信息:作为权宜之计,我目前正在返回所有结果,然后在内存中取前 X,但我不希望这是永久的,因为查询可以返回接近 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 因为我的选择返回多个属性。

4

1 回答 1

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();
于 2012-10-26T11:36:45.647 回答