2011-01-26 12 views
13

Używam NHibernate 3.0 zarówno z dostawcą LINQ, jak i QueryOver. Czasami chcę danych związanych z obciążeniem i nadchodzi metoda "Fetch" do ratowania, zarówno w LINQ i QueryOver. Teraz mam specjalny scenariusz gdzie chcę chętny obciążenia nieruchomości nie bezpośrednio na drugim poziomie, jak:NHibernate 3. Alternatywy dla "ThenFetch" w QueryOver

Foo f = ...; 
f.A.B.C 

z LINQ to nie ma problemu, jak to tylko możliwe „łańcuch” pobiera z zastosowaniem metody „ThenFetch” na przykład:

var result = Session.Query<Foo>().Fetch(a => a.A).ThenFetch(b => b.B).ThenFetch(c => c.C).ToList(); 

W QueryOver nie ma takiej metody, więc jak mogę osiągnąć ten sam wynik?

Z góry dziękuję.

Odpowiedz

16

I rzeczywiście udało się rozwiązać ten problem przy użyciu dwóch różnych podejść:

zbliżasz:

Session.QueryOver<Foo>().Fetch(x => x.A).Fetch(x => x.A.B).Fetch(x => x.A.B.C) 

Podejście drugie:

A a = null; 
B b = null; 
C c = null; 

Session.QueryOver<Foo>() 
    .JoinAlias(x => x.A,() => a) 
    .JoinAlias(() => a.B,() => b) 
    .JoinAlias(() => b.C,() => c) 

Obie prace (choć nie jestem do końca pewien, czy jeden z nich wygenerował "wewnętrzny", a drugi "zewnętrzny").

+0

dwa podejścia wydaje się działać tylko na jeden do jednego, to nie na zbiorach. – Phill

+5

Biorę to z powrotem, to działa, jeśli określisz typ łączenia dla kolekcji, domyślnie próbuje wewnętrznego sprzężenia. Jeśli podasz lewe sprzężenie zewnętrzne, działa ono idealnie. – Phill

+0

Czy FetchType (Eager, Lazy, Default) nie jest potrzebny po pobraniu()? –

4

myślę, że można zrobić z JoinQueryOver

IQueryOver<Relation> actual = 
    CreateTestQueryOver<Relation>() 
    .Inner.JoinQueryOver(r => r.Related1) 
    .Left.JoinQueryOver(r => r.Related2) 
    .Right.JoinQueryOver(r => r.Related3) 
    .Full.JoinQueryOver(r => r.Related4) 
    .JoinQueryOver(r => r.Collection1,() => collection1Alias) 
    .Left.JoinQueryOver(r => r.Collection2,() => collection2Alias) 
    .Right.JoinQueryOver(r => r.Collection3) 
    .Full.JoinQueryOver(r => r.People,() => personAlias); 
16

tylko jako ciekawostkę, wyślę odpowiedź dali mi na NHibernate Jira:

query 
    .Fetch(p => p.B) 
    .Fetch(p => p.B.C) // if B is not a collection ... or 
    .Fetch(p => p.B[0].C) // if B is a collection ... or 
    .Fetch(p => p.B.First().C) // if B is an IEnumerable (using .First() extension method) 
+0

Dziękujemy! To było dokładnie to, czego potrzebowałem. – adamjcooper