2011-08-22 15 views
9

これを行う方法は数時間前から検索されていますが、何か助けになるとは思えません。ここでnhibernate queryoverサブクエリと結合して集約カラムを取得する

はデータベースモデルである:

enter image description here

これは私が実行しようとしていますSQLクエリです:

SELECT b.*, a.Assignments FROM Branch b LEFT JOIN (
     SELECT b.BranchID , COUNT(ab.BranchID) AS Assignments 
     FROM Branch b LEFT JOIN AssignmentBranch ab ON b.BranchID = ab.BranchID 
     GROUP BY b.BranchID 
    ) a ON b.BranchID = a.BranchID 

だから、基本的に、私は枝のリストを返すようにしたいとそのブランチの割り当ての数を表す新しい列。ここで

支店モデル

public class Branch : IEntity<int> 
{ 
    public virtual int ID 
    { 
     get; 
     set; 
    } 

    public virtual string Name { get; set; } 

    public virtual IList<AssignmentBranch> Assignments { get; set; } 

} 

AssignmentBranchモデル

public class AssignmentBranch : IEntity<int> 
{ 
    public virtual int ID 
    { 
     get; 
     set; 
    } 

    public virtual DateTime AssignedOn { get; set; } 

    public virtual Branch Branch { get; set; } 
} 

は私のNHibernateの構成です:

<class name="Branch" table="Branch"> 

<id name="ID" column="BranchID"> 
    <generator class="identity"></generator> 
</id> 

<property name="Name"/> 

<bag name="Assignments" cascade="none" inverse="true"> 
    <key column="BranchID"/> 
    <one-to-many class="AssignmentBranch"/> 
</bag> 

<class name="AssignmentBranch" table="AssignmentBranch"> 

<id name="ID" column="AssignmentBranchID"> 
    <generator class="identity"></generator> 
</id> 

<property name="AssignedOn" /> 
<property name="FromDate" /> 
<property name="ToDate" /> 

<many-to-one name="Assignment" column="AssignmentID" /> 
<many-to-one name="Branch" column="BranchID" /> 

私はこれをいくつかの方法で試しましたが、QueryOverを使用してサブクエリに参加する方法を見つけることができないようです。

私はこのように試してみました:

// aliases 
Branch branch = null; AssignmentBranch assignment = null; 

var subquery = QueryOver.Of<Branch>(() => branch) 
    .Where(() => branch.Project.ID == projectID) 
    .JoinQueryOver<AssignmentBranch>(() => branch.Assignments,()=> assignment, 
            NHibernate.SqlCommand.JoinType.LeftOuterJoin) 
    .SelectList(list => list 
         .SelectGroup(x=>x.ID) 
         .SelectCount(()=>assignment.ID) 
        ); 

    var query = session.QueryOver<Branch>(()=>branch) 
        .JoinAlias(???) // how can I join with a sub-query? 
        .TransformUsing(Transformers.AliasToBean<BranchAssignments>()) 
        .List<BranchAssignments>(); 

誰も私を助けてくださいことはできますか?それはここに同様の質問の数百を読んだ後

答えて

12

を、

ありがとう...多分そこに私が行方不明だということを、他のよりよい解決策があり、正確に、参加サブ はCosminである必要はありません。私は答えを見つけました:相関サブクエリ。このように:

// aliases 
Branch branch = null; AssignmentBranch assignment = null; 

var subquery = QueryOver.Of<AssignmentBranch>(() => assignment) 
    .Where(() => assignment.Branch.ID == branch.ID) 
    .ToRowCountQuery(); 

var query = session.QueryOver<Branch>(() => branch) 
    .Where(() => branch.Project.ID == projectID) 
    .SelectList 
    (
     list => list 
     .Select(b => b.ID) 
     .Select(b => b.Name) 
     .SelectSubQuery(subquery) 
    ) 
    .TransformUsing(Transformers.AliasToBean<BranchAssignments>()) 
    .List<BranchAssignments>(); 

私の答えはthis oneです。

+0

いいだろうLINQで私の心に来ることの一つ(私は考えていない、最も効率的な方法)

var branches = session.QueryOver<Branch>().Future(); var assignmentMap = session.QueryOver<BranchAssignment>() .Select( Projections.Group<BranchAssignment>(ab => ab.Branch.Id).As("UserId"), Projections.RowCount()) .Future<object[]>() .ToDictionary(o => (int)o[0], o => (int)o[1]); return branches.Select(b => new { Branch = branch, AssignmentCount = assignmentMap[branch.Id] }); 

。私はあなたがBranchオブジェクト全体といくつかのプロパティだけでなく必要と思った。 – Firo

+0

いくつかのブランチプロパティと割り当ての数を持つカスタムエンティティを設定する必要があります。それにもかかわらず、返信する時間をとってくれてありがとう、私はあなたの答えはまた面白いと思う。 – noir

+0

これにより、左結合ではなくネストされた副問合せが作成されます。 SQLクエリオプティマイザが私を驚かせてくれました:-) –

2

これは、現在のところFROM句に文を入れることができないため、QueryOverではそれほど簡単ではありません。それは確かに

var branchesWithAssignementCount = session.Query<Branch>() 
    .Select(b => new { Branch = b, AssignmentCount = b.Branch.Count }) 
    .ToList(); 
関連する問題