2011-05-31 18 views
5

Bir öğe içeren bir alt öğe içeren bir üst nesneye sahibim, çocuk koleksiyonunda 3 öğe içeren bir "torun" koleksiyonu var.NHibernate ThenFetchMany yinelenen çocukları alıyor

Parent parentObject = session.Query<Parent>() 
    .FetchMany(x => x.Children) 
    .ThenFetchMany(x => x.GrandChildren) 
    .Where(x => x.Id = "someparentid") 
    .Single(); 

şöyle

Ben Ne bulgu değilim orada yinelenen çocuklar nesnelerin vardır olmalıdır zaman üst nesnenin bağlı (toplamda 3) olmasıdır NHibernate kullanarak veritabanından ana nesnesi yükleme am sadece bir. (Her çocuğa doğru şekilde bağlanmış 3 torun nesnesi vardır.) Çocuk koleksiyonunu yüklemek için istekli sadece doğru şekilde çalışır.

Yinelenen çocuklar olmadan tam üst nesnenin yüklenmesini nasıl başarabileceğimi biliyor musunuz?

cevap

2

Ben QueryOver kullanarak cevap here kullanmayı başardı, doğru nesneleri ederken yükleyen Sen koleksiyonları olarak çocuklara ve torunlara tanımlamanız gerekir Verimli SQL oluşturma (büyük bir birleştirme yerine tablo başına seçer).

1

NHibernate ile yapamazsınız (sonucunuzu EF4 ile yapabileceğinizi sanmıyorum) çünkü sonuç Kartezyen bir üründür. Tüm tablolardan tüm sonuçları alıyorsunuz.

NHibernate, sonuçların her iki koleksiyondan da kök dizinine nasıl eşleneceğini bilmiyor. Yani her Çocuk için, aynı sayıda GrandChildren kazanırsınız ve her bir GrandChildren için aynı sayıda Çocukla karşılaşırsınız.

+0

- düzenlemek için teşekkürler, olmadı sabah kahvesi henüz :) – Phill

+0

ben Oluşturulmakta olan SQL sorgusunun profilini ve her iki tarafta da birincil anahtarda ve yabancı anahtarda birleştirme koşuluyla iki tane sol bağlantı vardır, bu yüzden bir kartezyen ürün olmadığından emin değilim. Bunu geçmişte LinqToSql kullanarak başardım. – Simon

+0

@Simon - Sorguyu alın ve SQL Server Management Studio'ya koyun ve sorguyu çalıştırın, tüm tablolardan tüm sonuçları görürsünüz. Aynı sonucu elde etmek mümkündür, ancak HQL yazmanız gerekir. Derin nesne grafikleri için Ayende'nin bloguna bakın - http://ayende.com/blog/2580/efficently-loading-deep-object-graphs – Phill

5

Çocuklar ve GrandChildren'i ayarlandıysanız, kartezyen ürünü kullanabilirsiniz.

public class Parent 
{ 
    ... 
    public virtual ICollection<Child> Children { get; set; } 
    ... 
} 

public class Child 
{ 
    ... 
    public virtual ICollection<GrandChild> GrandChildren { get; set; } 
    ... 
} 

Ve (FluentNHibernate kullanarak) eşlemenizde:

public class ParentMapping : ClassMap<Parent> 
{ 
    public ParentMapping() 
    { 
     ... 
     HasMany(x => x.Children) 
      .KeyColumn("ParentID") 
      .Inverse 
      .AsSet() 
     ... 
    } 
} 

public class ChildMapping : ClassMap<Child> 
{ 
    public ChildMapping() 
    { 
     ... 
     HasMany(x => x.GrandChildren) 
      .KeyColumn("ChildID") 
      .Inverse 
      .AsSet() 
     ... 
    } 
} 
+0

Kesin olmak gerekirse, sorgu hala kartezyen ürünü verir, ancak tek bir Perent elde edersiniz. –

+0

Bu yaklaşıma QueryOver kullanarak yaşamayacağınız bir dezavantaj var mı? –

+0

Bunun için teşekkürler. Benzer bir durumda AsSet yönergesinin daha fazla kopyalamaya yetmeyeceğini buldum. – mabian69

1

Eğer Linq kullanıyorsanız, bu onu kolaylaştırabilirsiniz:

int parentId = 1; 
var p1 = session.Query<Parent>().Where(x => x.ParentId == parentId); 

p1 
.FetchMany(x => x.Children) 
.ToFuture(); 

sess.Query<Child>() 
.Where(x => x.Parent.ParentId == parentId); 
.FetchMany(x => x.GrandChildren) 
.ToFuture(); 

Parent p = p1.ToFuture().Single(); 
burada

ayrıntılı açıklaması: http://www.ienablemuch.com/2012/08/solving-nhibernate-thenfetchmany.html J0K @

+0

Teşekkürler Michael, bunu kanıtlamak için kod örneklememiş olmama rağmen, bu örneklerin tümü, getirilen çocukların (alması gereken torunları da var) başarısız olan ebeveynler arasında çoktan çoğa ilişki içerisindedir. Tüm bu örneği denedim (ve diğerleri) ve hepsi hala bu durumda kartezyen ürünler üretiyor – PandaWood

+0

Bu harika çalışıyor! –