2009-05-13 7 views
8

Ich muss die folgende funktionierende HQL-Abfrage mithilfe der Kriterien-API replizieren.Unterstützt die NHibernate-Kriterien-API Projektionen für Auflistungseigenschaften?

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

Die Abfrage wählt alle untergeordneten Elemente aus, die bestimmte Kriterien erfüllen, die zu übergeordneten Elementen gehören, die ein anderes Kriterium erfüllen. In meinem Beispiel sind beide Kriterien einfache Id-Gleichheiten, aber sie könnten alles sein.

Aus irgendeinem Grund gibt die äquivalente Kriterien-API-Abfrage eine Liste mit der richtigen Anzahl von Elementen zurück, aber diese Elemente sind alle null.

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

Warum geben diese beiden Abfragen nicht die gleichen Ergebnisse zurück?

Hier ist die generierten SQL aus der Abfrage 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 

Und hier ist die SQL von der Abfrage Kriterien API:

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 

Beachten Sie, dass die zwischen Eltern und Kind ist unidirektional verbinden. Die untergeordnete Entität hat keine Referenzeigenschaft, die auf ihr übergeordnetes Element verweist.

Kann jemand eine Alternative vorschlagen, mit der ich diese Einschränkung umgehen könnte?

+0

Warum gibt es child1_.childid> @ p1 in der Abfrage von der Kriterien-API? –

+0

Hoppla, das sollte gleich sein. –

Antwort

1

Es sieht so aus, als wollten Sie nur die Kinder zurück, also müssen Sie Ihre Kriterien ändern, um den Typ der untergeordneten Objekte zu erhalten, und dann die Eltern-ID als Auswahl verwenden.

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

Die Verbindung zwischen Eltern und Kind ist unidirektional. Die untergeordnete Entität hat keine Referenzeigenschaft, die auf ihr übergeordnetes Element verweist, sodass ich die Beziehung in dieser Richtung nicht durchlaufen kann. –

+0

Es würde saugen .. aber Sie könnten die Eltern auf die Kinder in einer geschützten Eigenschaft oder private Variable zuordnen, die Sie nicht verwenden .... – sirrocco