2011-01-16 5 views
11

Ich versuche, mit nHibernate diese Linq Abfrage unten zu laufen 3.nHibernate 3 - LEFT JOIN Wieder Linq Lösung

var items = from c in session.Query<tbla>() 
     join t in session.Query<tblb>() on c.Id equals t.SomeId into t1 // use left join on trades. 
     from t2 in t1.DefaultIfEmpty() 
select new {item = c, desc = t2.Description}; 

Dies ist die Aktie Weg, um eine LEFT JOIN in Linq meines Wissens durchzuführen. Es gibt mir jedoch eine nicht unterstützte Ausnahmebedingungsnachricht. Wie kann ich einen einfachen Link-Join ohne Rückgriff auf HQL erreichen? Dies scheint etwas albern, dass ein ORM, so weit verbreitet wie nHibernate, etwas nicht unterstützen kann, das so fussläufig ist wie ein linker Join.

[Bearbeiten]

Ich habe unten die richtige Antwort auf meine eigene Frage stellen.

+0

Ich bin verloren. Wo sind die Entsprechungen für "auf c.Id gleich t.SomeId in t1" und "new {item = c, desc = t2.Description}" im Beispiel? Können Sie das Beispiel und/oder die Kommentare erweitern? – mayu

+0

Die angenommene Antwort ist falsch. Warum reichen Sie nicht Ihre eigene Antwort ein? Ich würde dafür stimmen. – mayu

+0

Guter Anruf Ich habe meine Bearbeitung zu einer Antwort verschoben. Die Join-Magie passiert in der SelectList-Klausel dieses Ausdrucks. Hoffentlich hilft das. Die zweite Abfrage ist für die erste Abfrage keine exakte Übereinstimmung, daher gibt es keinen Vergleich zwischen Apple und Apple. – James

Antwort

8

Nach weiteren Untersuchungen dazu; dies ist möglich (wenn auch nicht offensichtlich) in einer stark typisierten Weise unter Verwendung von QueryOver zu erreichen. Der Trick besteht darin, äußere Query-Alias-Variablen in Verbindung mit WithAlias ​​und TransformUsing zu verwenden. Hier ist ein Beispiel, das links mit Filterung und Sortierung verbunden ist.

// Query alias variables 
entityTypeA anchorType = null; 
entityTypeB joinedType = null; 

var items = session.Query<entityTypeA>(()=>anchorType) 
      .Left.JoinAlias(() => anchorType.FieldName,() => joinedType) 
      .WithSubquery.WhereProperty(e => e.FieldD).In(myFilterList) 
      // bind property mappings using WithAlias 
      .SelectList(list => list 
         .Select(e => e.FieldNameA).WithAlias(()=> anchorType.FieldNameA) 
         .Select(e => e.FieldNameB).WithAlias(()=> anchorType.FieldNameB) 
         ) 
      .OrderBy(e => joinedType.FieldNameC).Desc 
      .TransformUsing(Transformers.AliasToBean<entityTypeA>()) // transform result to desired type. 
      .List<entityTypeA>(); 
+1

Es gibt ein Problem mit diesem Ansatz: Ihre abgerufene Entität verhält sich tatsächlich wie ein DTO (dh es wird nicht verfolgt) –

+0

Also, wenn sie sein müssen aktualisiert diese Lösung wird nicht funktionieren? –

1

Es wird noch nicht unterstützt. HQL ist deine einzige Wahl im Moment.

+0

Danke, ich hatte davor Angst. Gibt es vielleicht eine andere alternative Möglichkeit, dies zu tun, d. H. Eine Unterabfrage mit einem äußeren Satz usw.? – James

+1

Vielleicht ... aber ich würde eine einfache HQL anstelle einer komplexen LINQ verwenden ... –