2009-08-24 11 views
4

Ich versuche, ICriteria zu verwenden, um eine Abfrage zu erstellen, die eine Verknüpfung Bedingung hat. so aussiehtnHibernate ICriteria Join Bedingung

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

Die SQL Ich soll zu erzeugen versuchen Wenn ich ein Kriterium verwenden wie

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

Es wird die SQL generiert, unter dem ich nicht will.

Gibt es eine Möglichkeit, dies mit ICriteria oder HQL zu tun, wenn ICriteria nicht möglich ist?

Edit: Ich habe entdeckt, nHibernate 2.1 (die ich verwende) tut jetzt allow this. Ich bin mir nicht sicher über ICriteria, das ist meine Vorliebe.

+0

Suche für genau die gleiche Sache in Kriterien. Wir brauchen das mit Ausdruck. – madcapnmckay

+0

Nicht viel von einem SQL-Typ, aber warum sollten Sie die erste Option über die zweite wollen, geben sie nicht die gleichen Ergebnisse? – pythonandchips

+0

Hallo Colin, sie geben nicht die gleichen Ergebnisse. – Craig

Antwort

0

Sie können IQuery in Verbindung mit ISQLQuery verwenden. Das ist kein Criteria-Mechanismus, aber es könnte Ihnen helfen.

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; 

Hope this funktioniert, wenn Sie NHibernate verwenden 2

1

Wenn Sie nicht einen Weg finden, richtig join zu bilden, können Sie einen einfachen Trick machen: einfach Ihre Einschränkung WHERE t.ContactType = 'Email' OR t.ClientID IS NULL sein machen - hoffentlich, es ist mit NHibernate möglich.

+0

Sie müssen die Verknüpfung zu einer inneren Verknüpfung ändern, wenn Sie diese Problemumgehung verwenden. –

+0

@Jamie Nein. Es ist 'LEFT JOIN' jetzt und es ist genug. –

3

Ich würde das nicht tun. Der linke Outer-Join lässt NH-Clients trotzdem laden, der Filter für E-Mail-Kontakte würde nur E-Mail-Kontakte laden ... bis er die Kontaktsammlung initialisiert und sowieso alles lädt.

Wenn es nur E-Mail-Kontakte laden würde, würde es in unvollständigen Objekten im Speicher landen. Dies ist normalerweise keine gute Idee, insbesondere wenn Sie auch Daten in derselben Transaktion ändern.

In Ihrer Situation würde ich versuchen, E-Mail-Kontakte direkt zu laden und navigieren Sie vom Kontakt zum Kunden.

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