2009-06-02 19 views
24

ile çocuk istifleme yükleme Çocuk kökeni ve tüm çocuk toplama ve toplama üyeleri istekli yük yüklemek istiyorum.NHibernate

FluentNHibernate'de SetFetchMode'u kullanmaya çalışıyorum, ancak 3 seviyeli bir derinliğe sahip olduğum için çocuk koleksiyonlarından birinde kopyaları alıyorum. DistinctRootEntityResultTransformer maalesef sadece kök kopyalarını kaldırır.

return Session.CreateInvoiceBaseCriteria(query, archived) 
    .AddOrder(new Order(query.Order, query.OrderType == OrderType.ASC)) 
    .SetFetchMode("States", FetchMode.Eager) 
    .SetFetchMode("Attestations", FetchMode.Eager) 
    .SetFetchMode("AttestationRequests", FetchMode.Eager) 
    .SetFetchMode("AttestationRequests.Reminders", FetchMode.Eager) 
    .SetResultTransformer(new DistinctRootEntityResultTransformer()) 
    .List<Invoice>(); 

Birden çok sorguyu veya buna benzer bir şeyi kullanabilir miyim? Ayrıca, bu yaklaşım veritabanından gereksiz derecede büyük sonuç kümeleriyle sonuçlanmaz mıydı?

Herhangi bir öneriniz var mı?

cevap

0

Eğer, ben bu yazıda bakarak öneriyoruz aradığınız tam olarak ne olmayabilir süre:

Eager loading aggregate with many child collections

bu siteden geri kalanı bakmaya Eğer tartışmak daha bulabilir.END_PARAGRAPH istekli yükleme ve diğer büyük nHibernate şeyler.

+2

Gerçekten de iyi bir yazı, ancak durumuma uygulayabilirseniz emin değilim. Belirli bir kök varlığı yüklemeye istekli hakkında makalede açıklanan çözüm, benim sorun, kök varlıkların bir toplama istekli yüklemek istiyorum. Eğer MultiCritera kullanacak olsaydım, belirli bir varlık belirtmeden tüm farklı sorguları birbirine bağlamanın bir yolunu bulmalıyım. Öneriler bu nasıl yapılabilir? – Kristoffer

+0

Bu örnekte yalnızca bir ek hiyerarşi düzeyi vardır, ancak hiçbir QuQuery/MultiCriteria oldukça işe yaramaz gibi görünen torunlara sahip değildir, çünkü daha sonraki sorgular önceki sorguların sonuçlarına başvuruda bulunamaz (Query # 1: select rootObjects r left join fetch children c nerede ...; Sorgu # 2: torun seçin c ebeveynin içinde c). –

8

Bir çözüm bulduk ama güzel değil. Öncelikle tüm Fatura Kimliklerini bulup buluyorum, sonra bunları çok amaçlı olarak kullanıyorum ve sonuçta HashedSet ile sonuçları filtreliyorum. Çok sayıda öğe nedeniyle bazen normalt Restriction.In kullanamadım ve bir dize olarak göndermek zorunda kaldı.

Önerilen herhangi bir ince ayar?

var criteria = Session.CreateInvoiceBaseCriteria(query, archived) 
    .SetProjection(Projections.Id()); 

var invoiceIds = criteria.List<int>(); 
if (invoiceIds.Count > 0) 
{ 
    var joinedIds = JoinIDs(criteria.List<int>()); // To many ids to send them as parameters. 

    var sql1 = string.Format("from Invoice i inner join fetch i.States where i.InvoiceID in ({0}) order by i.{1} {2}", joinedIds, query.Order, query.OrderType.ToString()); 
    var sql2 = string.Format("from Invoice i inner join fetch i.AttestationRequests where i.InvoiceID in ({0})", joinedIds); 
    var sql3 = string.Format("from Invoice i inner join fetch i.Attestations where i.InvoiceID in ({0})", joinedIds); 

    var invoiceQuery = Session.CreateMultiQuery() 
     .Add(sql1) 
     .Add(sql2) 
     .Add(sql3); 

    var result = invoiceQuery.List()[0]; 

    return new UniqueFilter<Invoice>((ICollection)result); 
} 

return new List<Invoice>(); 
+0

Bu garip, Attestations tek sorgu olarak getirilir. – Kristoffer

+0

+1, Bunu başarmak için aslında (ve ne yazık ki) en iyi yoldur (performans açısından). –

+0

Benzer bir durumdayım (bir kerede 3 seviyeyi çekmeye çalışıyorum). Çözümünüz kopyalardan kurtulsa da, sadece 2 seviye derinlikli görünmektedir. Orijinal sorunuz, cevabınıza dahil olmayan "AttestationRequests.Reminders" adında bir 3. seviye içeriyordu. – MylesRip

2

Sorunuzu yanıtlamak için: evet, sonuç büyük sonuçlara neden olur.

ben öneririm: sadece safça istekli belirli yerlerde On

  • getirilirken olmadan sorguları yazmak

    • , bir istekli getirme koydu ama sorguda
    • başına yalnızca bir gerçekten performans sorunları alırsanız hangi sizi indekslerle çözülemez veya sorguları ve haritalama stratejilerini geliştirerek, çözümünüzü çoklu sorgularla kullanın.