2009-05-13 12 views
8

Je dois répliquer la requête HQL de travail suivante en utilisant l'API de critères.Est-ce que l'API NHibernate Criteria prend en charge les projections sur les propriétés de collection?

session.CreateQuery(
    "select c " + 
    "from Parent p " + 
    "inner join p.Children c " + 
    "where p.Id = 9 " + 
    "and c.Id = 33") 
    .SetMaxResults(3) 
    .List(); 

La requête sélectionne tous les enfants qui satisfont à certains critères qui appartiennent aux parents qui satisfont un autre critère. Dans mon exemple, les deux critères sont des égalités Id simples, mais ils pourraient être n'importe quoi.

Pour une raison quelconque, la requête API de critères équivalents renvoie une liste avec le bon nombre d'éléments, mais ces éléments sont tous null.

session.CreateCriteria(typeof (Parent)) 
    .Add(Restrictions.Eq("Id", 9)) 
    .CreateCriteria("Children") 
    .Add(Restrictions.Eq("Id", 33)) 
    .SetProjection(Projections.Property("Children")) 
    .SetMaxResults(3) 
    .List(); 

Pourquoi ces deux requêtes ne renvoient-elles pas les mêmes résultats?

Voici le SQL généré à partir de la requête HQL:

SELECT TOP 3 childid7_, 
       name7_ 
FROM  (SELECT children1_.childid     AS childid7_, 
       children1_.name     AS name7_, 
       Row_number() 
        OVER(ORDER BY current_timestamp) AS __hibernate_sort_row 
      FROM dbo.parent parent0_ 
       LEFT OUTER JOIN dbo.child children1_ 
        ON parent0_.parentid = children1_.parentid 
      WHERE (parent0_.parentid = 9) 
       AND (children1_.childid = 33)) AS QUERY 
WHERE QUERY.__hibernate_sort_row > 0 
ORDER BY QUERY.__hibernate_sort_row 

Et voici le SQL de la requête de l'API Critères:

SELECT TOP 3 y0_ 
FROM  (SELECT this_.parentid      AS y0_, 
       Row_number() 
        OVER(ORDER BY current_timestamp) AS __hibernate_sort_row 
      FROM dbo.parent this_ 
       INNER JOIN dbo.child child1_ 
        ON this_.parentid = child1_.parentid 
      WHERE this_.parentid = @p0 
       AND child1_.childid = @p1) AS QUERY 
WHERE QUERY.__hibernate_sort_row > 0 
ORDER BY QUERY.__hibernate_sort_row 

Notez que la jonction entre le parent et l'enfant est à sens unique. L'entité enfant n'a pas de propriété de référence pointant vers son parent.

Quelqu'un peut-il suggérer une alternative qui me permettrait de contourner cette limitation?

+0

Pourquoi yat-il child1_.childid> @ p1 dans la requête de l'API de critères? –

+0

Oups, ça devrait être un égal. –

Répondre

1

Il semble que vous ne souhaitiez que récupérer les enfants. Vous devez donc modifier vos critères pour obtenir le type des objets enfants, puis utiliser l'ID parent comme sélection.

session.CreateCriteria(typeof (Child)) 
.Add(Restrictions.Eq("Id", 33)) 
.CreateCriteria("Parent") 
.Add(Restrictions.Eq("Id", 9)) 
.SetProjection(Projections.Property("Children")) 
.SetMaxResults(3) 
.List(); 
+0

La jointure entre parent et enfant est unidirectionnelle. L'entité enfant n'a pas de propriété de référence pointant vers son parent, donc je ne peux pas traverser la relation dans cette direction. –

+0

Il sucerait .. mais vous pouvez mapper le parent sur les enfants dans une propriété protégée ou variable privée que vous n'utilisez pas .... – sirrocco

Questions connexes