2016-05-30 4 views
1

メソッドの入力に応じて、結合を使用するかどうかを問合せする必要があります。私はどちらか動的結合と切り捨てを使用するQueryOver

  • が与えられた異なるAccountはどちらかKeyUser

または

  • として入力されたすべてのAccountsがすべて取得取得したい

    Account 
    { 
        Group Group; 
        Account KeyUserInteral; 
        Account KeyUserExternal; 
        DateTime DeactivationDate; 
    } 
    
    Group 
    { 
        Account KeyUserInteral; 
        Account KeyUserExternal; 
    } 
    

    :次のモデルを考えますAccounts所与異なるAccountはいずれかKeyUser又はとして入力されAccountsかのみ活性が含まれるように結果DeactivationDateフィルタに応じて、次にAccount.GroupのいずれかKeyUser

として入力されます。このため

、私はこの方法を使用して、それを試してみました:

public IList<Account> ListByKeyUser(int keyUserId_, bool includeGroupAccounts_, bool onlyActive_) 
{ 
    Account keyUser = Get(keyUserId_); 

    Disjunction keyUserRestriction = new Disjunction(); 
    keyUserRestriction.Add<Account>(acc_ => acc_.KeyUserInternal == keyUser || acc_.KeyUserExternal == keyUser); 

    IQueryOver<Account, Account> query = Session.QueryOver<Account>(); 

    if (includeGroupAccounts_) { 
     query.JoinQueryOver(acc_ => acc_.Group, JoinType.LeftOuterJoin) 
      .Where(grp_ => grp_.KeyUserInternal == keyUser || grp_.KeyUserExternal == keyUser); 
    } 

    query.Where(keyUserRestriction); 

    if (onlyActive_) { 
     query.Where(acc_ => acc_.DeactivationDate > DateTime.Now); 
    } 

    return query.OrderBy(acc_ => acc_.Name).Asc.List<Account>(); 
} 

Unfortunatley、作成されたSQLは、私が必要と正確に何ではありません。(それは本当に面白いではないと私は思うSELECTを除外)

SELECT [...] 
FROM accounts this_ left outer join groups group1_ on this_.userGroup=group1_.id 
WHERE 
(group1_.keyUserInternal = @p0 or group1_.keyUserExternal = @p1) 
and 
((this_.keyUserInternal = @p2 or this_.keyUserExternal = @p3)) 
and this_.deactivationDate > @p4 
ORDER BY this_.name asc; 
私は必要なもの

はこれです:

SELECT [...] 
FROM accounts this_ left outer join groups group1_ on this_.userGroup=group1_.id 
WHERE 
((group1_.keyUserInternal = @p0 or group1_.keyUserExternal = @p1) 
or (this_.keyUserInternal = @p2 or this_.keyUserExternal = @p3)) 
and this_.deactivationDate > @p4 
ORDER BY this_.name asc; 

基本的に、私はちょうど秒に必要omehow "join condition"を "or"に移動します。

if (includeGroupAccounts_) { 
    query.JoinQueryOver(acc_ => acc_.Group, JoinType.LeftOuterJoin); 
    keyUserRestriction.Add<Account>(acc_ => acc_.Group.KeyUserInternal == keyUser || acc_.Group.KeyUserExternal == keyUser); 
} 

しかし、それが作成されます:私は論理和にどこを追加することで、それを試してみました

全く Groupが参加無視
SELECT [...] 
FROM accounts this_ left outer join groups group1_ on this_.userGroup=group1_.id 
WHERE 
((this_.keyUserInternal = @p0 or this_.keyUserExternal = @p1) 
or (this_.keyUserInternal = @p2 or this_.keyUserExternal = @p3)) 
and this_.deactivationDate > @p4 
ORDER BY this_.name asc; 

...

をどのように私はこの作業を行うことができますか?

答えて

0

はもう少し解決策として、以下を返さ掘り:

if (includeGroupAccounts_) { 
    Group groupAlias = null; 
    query.JoinAlias(acc_ => acc_.Group,() => groupAlias, JoinType.LeftOuterJoin); 
    keyUserRestriction.Add(() => groupAlias.KeyUserExternal == keyUser || groupAlias.KeyUserInternal == keyUser); 
} 

これは「日時チェックしながら、「または」に含まれる「どこに参加」私は必要な正確にSQLをもたらします、 "まだすべてのための"と "です。

SELECT [...] 
FROM accounts this_ left outer join groups groupalias1_ on this_.userGroup=groupalias1_.id 
WHERE (
    (this_.keyUserInternal = @p0 or this_.keyUserExternal = @p1) 
    or (groupalias1_.keyUserExternal = @p2 or groupalias1_.keyUserInternal = @p3) 
) 
and this_.deactivationDate > @p4 
ORDER BY this_.name asc 
関連する問題