2009-08-24 22 views
4

ICriteriaを使用して、参加 条件を持つクエリを作成しようとしています。私はそれは私が望んでいない、それ以下のSQLを生成しますnHibernate ICriteria参加条件

m_ClientRepository.QueryAlias("client") 
    .CreateCriteria("client.Contacts", "c", JoinType.LeftOuterJoin) 
    .Add(Restrictions.Eq("c.ContactType", ContactType.Email)); 

のような基準を使用している場合は、私が生成しようとしているSQLは、この

SELECT c.ClientID 
FROM Client c 
LEFT OUTER JOIN ClientContact t on c.ClientID = t.ClientID AND 
t.ContactType = 'Email' 

のようになります。

SELECT c.ClientID 
FROM Client c 
LEFT OUTER JOIN ClientContact t on c.ClientID = t.ClientID 
WHERE t.ContactType = 'Email' 

ICriteriaを使用できない場合、ICriteriaまたはHQLでこれを行うにはどうしてですか?

編集:私はnHibernate 2.1(私が使用しています)がallow thisになったことを発見しました。しかし、ICriteriaについてはわかりませんが、これは私の好みです。

+0

私が探していますでクライテリアとまったく同じものです私達はwithの表現が必要です。 – madcapnmckay

+0

SQLの人は大したことではありませんが、2番目のオプションよりも最初のオプションを望む理由は同じですか? – pythonandchips

+0

こんにちはコリン、彼らは同じ結果を与えることはありません。 – Craig

答えて

0

ISQLQueryと組み合わせてIQueryを使用できます。それはCriteriaの仕組みではありませんが、それはあなたを助けるかもしれません。あなたは正しいjoinを形成する方法を見つけることができません場合は、NHibernateの2

0
from s in Session.Linq<Client> left join cc in c.Contacts 
     on 
     new { c.ClientID , cc.ClientID } 
     equals 
     new { cc.ContactType, "Email" } 
     select c.ClientId; 

希望の作品は、簡単なトリックを行うことができますちょうどあなたの制限がWHERE t.ContactType = 'Email' OR t.ClientID IS NULLことにする - うまくいけば、それはNHibernateで可能です。

1

を使用している場合は、この

+0

この回避策を使用する場合は、内部結合に結合を変更する必要があります。 –

+0

@Jamie No.今はLEFT JOINですので十分です。 –

3

私はこれをしません。とにかく左の外部結合はNHのロードクライアントになります。電子メールの連絡先のフィルタは、連絡先のコレクションを初期化してすべてをロードするまで、電子メールの連絡先のみを読み込みます。

電子メールの連絡先だけを読み込むと、メモリ内の不完全なオブジェクトになります。これは、通常、同じトランザクション内のデータも変更している場合には、通常はお勧めできません。

あなたの状況で私は直接EMail連絡先を読み込み、連絡先から顧客にナビゲートしようとします。

session.CreateCriteria(typeof(Contact)) 
    .Add(Restrictions.Eq("c.ContactType", ContactType.Email));