bu nesne grafiği var: ArtıkLinq NHibernate ThenFetch birden fazla mülke
// Lots of stuff omitted for brevity; these are all virtual properties and there
// are other properties which aren't shown on all classes.
class A {
B b;
C c;
DateTime timestamp;
}
class B {
X x;
Y y;
}
class X {
int id;
}
class C { }
class Y { }
or to put it more simply,
a = {
b: {
x { id: int },
y: { }
},
c: { },
timestamp: DateTime
}
ben A
s listesini döndürmek için gidiyorum bir sorgu yapıyorum ve tüm bunların B
s ihtiyaç , C
s, X
s ve Y
s. Ayrıca onları B tarafından bir aramada gruplayacağım.
ILookup<B, A> GetData(List<int> ids) {
using (ISession session = OpenSession()) {
var query = from a in session.Query<A>()
where ids.Contains(a.b.x.id)
orderby A.timestamp descending
select a;
query = query
.Fetch(a => a.b)
.ThenFetch(b => b.x)
.Fetch(a => a.b)
.ThenFetch(b => b.y)
.Fetch(a => a.c);
return query.ToLookup(a => a.b);
}
}
birkaç nokta not:
- Bu, tüm veriler iade edilmesi gereken bir rapordur - sınırsız sonuçları bir sorun değildir.
ToLookup
kullanarak gruplamayı yapıyorum çünkügroup by
kullanmak, tüm gerçek değerlere ihtiyaç duyduğunuzda daha karmaşık görünüyor; bu nedenle, grupların veritabanını ve daha sonra gerçek değerleri için sorgulamanız gerekir.
Sorum düzgün getiriliyor stratejisini belirlemek için nasıl. Bunu yaptık yolu bu (bütün bx ve değerleriyle getirilen sahip) çalıştırmak için bulunan tek yoldur - ama yanlış görünüyor SQL üretir: Eğer gidiyor görebileceğiniz gibi
select /* snipped - every mapped field from a0, b1, x2, b3, y4, c5 - but not b6 */
from [A] a0
left outer join [B] b1
on a0.B_id = b1.BId
left outer join [X] x2
on b1.X_id = x2.XId
left outer join [B] b3
on a0.B_id = b3.BId
left outer join [Y] y4
on b3.Y_id = y4.YId
left outer join [C] c5
on a0.C_id = c5.CId,
[B] b6
where a0.B_id = b6.BId
and (b6.X_id in (1, 2, 3, 4, 5))
order by a0.timestamp desc
getirme için a.b
3 kez - b1
ve b3
için değer ve nerede yan tümce için b6
.
- Bunun, DB performansı üzerinde olumsuz bir etkisi olduğunu varsayalım - doğru muyum? yalnızca bir kez
a.b
getirir yani benim.Fetch
aramaları değiştirmek için bir yol - var mı?
- Bu benim sorunuma iyi bir yaklaşım mı?
Birincisi, bunların hepsi birçok bire haritalama görülebilir gibidir (orada sadece birinin bir A'da B ve onlardan bir listesi), bu yüzden tüm sorgu sadece olacak yük 4 kişiler. İkincisi, önerdiğiniz şey tam olarak istediğimin tam tersidir - sorgunun karmaşıklığını azaltmak yerine onu birden fazla sorguya bölerek artırdınız. İdeal sorgu aşağıdaki birleşimlere sahip olacak: 'dan [A] sol dış birleştirmeden [B] ...sol dış birleşim [X] on ... sol dıştaki birleşim [Y] on ... '. – configurator
Bir önceki yorumum ses geliyor sert; Sana yardım etmeye çalışmaktan caydırmak istemedim. Önceki yorumumdan hoşlanmasa bile, gayretinizi takdir ediyorum. – configurator
Ön yükleme ile ilgili varlıklar hakkında önerilen davranışı kontrol ettim. NHibernate Profiler'i Kullanarak bunların sadece bir kez alındığını görebiliyorum, bu yüzden bdrajer'ın oturumdaki verileri önbelleğe alma hakkında doğru olduğunu söylediğini doğrulayabiliriz. –