2011-01-16 16 views
11

che sto cercando di fare funzionare questa query LINQ seguito con NHibernate 3.NHibernate 3 - LEFT JOIN soluzione ri-Linq

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}; 

Questo è il magazzino modo per eseguire una sinistra unirsi LINQ a mia conoscenza. Tuttavia mi sta dando un messaggio di eccezione non supportato. Come posso ottenere un join di sinistra di base senza ricorrere a HQL? Questo sembra un po 'sciocco che un ORM prevalente come ibernato non possa supportare qualcosa di pedone come un join di sinistra.

[modifica]

ho messo la vera risposta alla mia domanda qui sotto.

+0

Mi sono perso. Dove sono gli equivalenti per "on c.Id equals t.SomeId in t1" e "new {item = c, desc = t2.Description}" nell'esempio? Potresti estendere l'esempio e/oi commenti? – mayu

+0

La risposta accettata è errata. Perché non invii la tua risposta? Io voterei per questo. – mayu

+0

Buona chiamata ho spostato la mia modifica su una risposta. La magia del join avviene nella clausola 'SelectList' di quell'espressione. Speriamo che questo aiuti. La seconda query non è una logica di corrispondenza esatta per la prima query, quindi non esiste un confronto tra le mele e le mele. – James

risposta

8

Dopo ulteriori ricerche su questo; questo è possibile (anche se non ovvio) da ottenere in modo fortemente tipizzato usando QueryOver. Il trucco è usare le variabili alias Query esterne insieme a WithAlias ​​e TransformUsing. Ecco un esempio che fa parte di sinistra con il filtraggio e l'ordinamento.

// 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

C'è un problema con questo approccio: la tua entità recuperata si comporta effettivamente come un DTO (cioè non è monitorata) –

+0

Quindi, se devono essere aggiornato questa soluzione non funzionerà? –

1

Non è ancora supportato. HQL è la tua unica scelta al momento.

+0

Grazie, ne avevo paura. C'è forse un altro modo alternativo non-hql di fare questo, sottoquery w/where clausola esterna ecc? – James

+1

Forse ... ma userei un semplice HQL invece di un complesso LINQ ... –