2009-08-24 8 views
4

J'essaie d'utiliser ICriteria pour créer une requête qui a une condition de jointure . Le SQL que je suis en train de générer devrait ressembler à cecinHibernate ICriteria Joindre la condition

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

Si j'utilise un critère comme

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

Il va générer le sql ci-dessous que je ne veux pas. Y a-t-il un moyen de le faire avec ICriteria ou HQL si ICriteria n'est pas possible? Editer: J'ai découvert nHibernate 2.1 (que j'utilise) maintenant allow this. Je ne suis pas sûr d'ICriteria, c'est ma préférence.

+0

Je suis à la recherche pour exactement la même chose dans les critères. Nous avons besoin de l'expression. – madcapnmckay

+0

N'étant pas beaucoup d'un gars sql mais pourquoi voudriez-vous la première option au cours de la seconde, ne donnent-ils pas les mêmes résultats? – pythonandchips

+0

Salut Colin, ils ne donnent pas les mêmes résultats. – Craig

Répondre

0

Vous pouvez utiliser IQuery conjointement avec ISQLQuery. Ce n'est pas un mécanisme de critères, mais cela pourrait vous aider.

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; 

espère que cela fonctionne si vous utilisez Nhibernate 2

1

Si vous ne trouvez pas un moyen de forme correcte join, vous pouvez faire un truc simple: il suffit de faire votre restriction soit WHERE t.ContactType = 'Email' OR t.ClientID IS NULL - espérons-le, il est possible avec NHibernate.

+0

Vous devrez changer la jointure en une jointure interne si vous utilisez cette solution de contournement. –

+0

@Jamie Non. C'est "LEFT JOIN" maintenant et c'est suffisant. –

3

Je ne ferais pas cela. La jointure gauche gauche permet de charger les clients de toute façon, le filtre pour les contacts de messagerie ne chargerait que les contacts de messagerie ... jusqu'à ce qu'il initialise la collection de contacts et charge tout de toute façon.

S'il ne chargeait que des contacts de messagerie, il se retrouverait dans des objets incomplets en mémoire. Ce n'est généralement pas une bonne idée, en particulier lorsque vous modifiez également des données dans la même transaction.

Dans votre situation, j'essaierais de charger les contacts EMail directement et de naviguer du contact au client.

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