2017-07-04 4 views
1

J'ai deux tables:Courant NHibernate QueryOver pour sélectionner des éléments non dans une autre table (join gauche)

tous: id | propA | propB | someOtherColumn

caché: id | propA | propB

et les classes correspondantes (mappée, aucune relation mappée encore)

Je voudrais obtenir toutes les lignes de la première table, moins les résultats qui par correspondance propA ou propB Propriété.

J'ai réussi à le faire par API Criteria mais j'aimerais voir comment cela est fait avec l'API QueryOver, si possible sans sous-requêtes mais avec une jointure à gauche exclue.

version Critères:

var dc1 = DetachedCriteria.For<hidden>() 
    .Add(Restrictions.IsNotNull(Projections.Property("propA"))) 
    .SetProjection(Projections.Property("propA")); 

var dc2 = DetachedCriteria.For<hidden>() 
    .Add(Restrictions.IsNotNull(Projections.Property("propB"))) 
    .SetProjection(Projections.Property("propB")); 



var query = db 
    .CreateCriteria<all>() 
    .Add(Restrictions.On<all>(c => c.someOtherColumn).IsLike("1")) 
    .Add(Subqueries.PropertyNotIn("propA", dc1)) 
    .Add(Subqueries.PropertyNotIn("propB", dc2)) 

qui donne à peu près:

SELECT all.* 
FROM all 
WHERE (all.someOtherColumn LIKE '1') 
    and all.propA not in (SELECT hidden.propA FROM hidden WHERE hidden.propA IS NOT NULL) 
    and all.propB not in (SELECT hidden.propB FROM hidden WHERE hidden.propB IS NOT NULL) 

Il est ok, mais il semble sage que ce serait une meilleure performance:

SELECT all.* 
FROM all 
LEFT JOIN hidden ON all.propA = hidden.propA 
LEFT JOIN hidden ON all.propB = hidden.propB 
WHERE hidden.propA IS NULL 
AND hidden.propB IS NULL 
AND (all.someOtherColumn LIKE '1') 

Si ce n'est pas possible de générer une telle déclaration avec des relations non mappées, je suis ouvert aux suggestions sur la cartographie.

Répondre

2

Il me semble qu'il n'est pas possible de créer des jointures sans relations mappées via QueryOver. Voir ceci answer.

Avec les sous-requêtes que vous pouvez faire quelque chose comme ceci:

All allAlias = null; 
var result = Session.QueryOver(() => allAlias) 
       .WhereRestrictionOn(x => x.someOtherColumn).IsLike('1') 
       .WithSubquery.WhereNotExists(QueryOver.Of<hidden>() 
        .Where(h => h.propA == allAlias.propB || h.propB == allAlias.propB) 
        .Select(h => h.Id)) 
       .List();