1

私は Nhibernate Query を使用しています。そこでは、ルート エンティティの子を積極的にロードするために、結合エイリアスに対して複雑なクエリを実行する必要があります。読み込み時に、子にあるものを含む、多数のプロパティによって返されるルート エンティティの結果をフィルター処理したいと考えています。

joinaliases を使用してこれをすべて正常に動作させましたが、ルート エンティティ Id 以外のプロパティで並べ替えたときに、返された結果をルート エンティティの上位 "X" インスタンスまでフィルタリングすることに困っています。子を取得しているため、SQL によって返される重複行が多数あります。.Take で結果の数をフィルタリングしようとすると、NHibernate が結果セットを個別のルート エンティティに折りたたむ前にテイクが実行されます。参考までに、私のドメイン モデルを次に示します。

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などを選択せず​​に、これをできるだけ効率的に行いたい.

このコミュニティは何を推奨していますか?

追加情報: 一時しのぎとして、現在、すべての結果を返し、メモリ内の上位 X を取得していますが、これを永続的にしたくありません。クエリは 10,000 近くのアイテムを返す可能性があるためです。トップ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 を実行しているため、select が複数のプロパティを返すため、WHERE IN を使用できません。

4

1 に答える 1

0

ユーザーが 1,000 未満のプロジェクトを持っている場合、これは機能する可能性があります

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 に答える