2010-06-23 13 views
5

nHibernate 2.1.2 kullanıyorum ve nhibernate'in iç içe çoktan bire varlıklar üzerinde sol dış birleştirme oluşturması gerektiği açıklandı. varlık kuruluşundan başlayarak 3. iç içe geçmiş nota üzerinde sol dış birleştirmeyi oluşturmaya başlıyor. İç katılmayı kullanmak için eşleme dosyasında aşağıdakileri ayarladım, eşleme dosyasında kaçırdığım bir şey var mı? Umarım birileri bana bunun hakkında bir ipucu verebilir. herhangi bir yardım için teşekkür ederiz!nhibernate, bire-bir varlık üzerinde sol dış birleştirme oluşturuyor

lazy="false" fetch="join" 

Örnek entites ve İlişkiler: Satış Kaydı - Çalışan - Organizasyon

nhibernate oluşturmak:

select... 
from sales 
inner join employee 
left outer join organization 

Sales.hbm.xml

<many-to-one name="Employee" insert="true" update="true" access="field.pascalcase-underscore" not-null="true" lazy="false" fetch="join"/> 
<column name="EmployeeId" not-null="true"/> 
</many-to-one> 

Employee.hbm.xml

<many-to-one name="Organization" insert="true" update="true" access="field.pascalcase-underscore" not-null="true" lazy="false" fetch="join"/> 
<column name="OrgId" not-null="true"/> 
</many-to-one> 
+1

Sorgu nasıl görünüyor? HQL veya kriterleri kullanıyor musunuz? –

+0

Sadece Entity.Fetch yapıyorum, btw HQL de ve aynı sorun ile test ettik. – ksang

+0

Bu sorunu modifiye nhibernate kaynağı tarafından düzelttim, nhibernate sadece ilk katma düzeyi için iç ortak sql üretecek olduğunu öğrendim. Belki birisi bana neden böyle davrandığını söyleyebilirdi. – ksang

cevap

4

NHibernate bir iç oluyorsa Bir üst tablosundan bir çocuk ve kimliğinden kimliğini yok (ama ikisi de bir) katıldı.

Örnek:

TableParent (ID, Name) 
    TableChild (ID, ID_TableParent, ....) 

nHibernate bir iç birleşim yaparsa, elde edersiniz: nHibernate bir sol dış birleşim yaparsa

select c.ID, c.ID_TableParent, p.Name 
from TableChild c 
inner join TableParent p on p.ID = c.ID_TableParent 

elde edersiniz:

select c.ID, c.ID_TableParent, p.ID, p.Name 
from TableChild c 
left outer join TableParent p on p.ID = c.ID_TableParent 

Ve çünkü, NHibernate iç çalışmalarının ardından ikinci sorgudan 2 öğe oluşturabilir. TableChild ve TableParent için bir varlık.

İlk sorguda yalnızca TableChild öğesinin elde edilmesi ve bazı durumlarda p.Name (ikinci düzeyde probalby) göz ardı edilir ve TableParent'e başvuran özelliklerin kontrol edilmesinde veritabanı istenir. NHibernate.SqlCommand ile

SysPermissionTree t = null; 
SysPermission p = null; 

return db.QueryOver<SysPermissionTree>() 
     .JoinAlias(x => x.Children,() => t, NHibernate.SqlCommand.JoinType.LeftOuterJoin) 
     .JoinAlias(() => t.Permissions,() => p, NHibernate.SqlCommand.JoinType.LeftOuterJoin) 
     .Where(x => x.Parent == null) 
     .TransformUsing(Transformers.DistinctRootEntity) 
     .List(); 

:

public class SysPermissionTree 
{ 
    public virtual int ID { get; set; } 
    public virtual SysPermissionTree Parent { get; set; } 
    public virtual string Name_L1 { get; set; } 
    public virtual string Name_L2 { get; set; } 

    public virtual Iesi.Collections.Generic.ISet<SysPermissionTree> Children { get; private set; } 
    public virtual Iesi.Collections.Generic.ISet<SysPermission> Permissions { get; private set; } 

    public class SysPermissionTree_Map : ClassMap<SysPermissionTree> 
    { 
     public SysPermissionTree_Map() 
     { 
      Id(x => x.ID).GeneratedBy.Identity(); 

      References(x => x.Parent, "id_SysPermissionTree_Parent"); 
      Map(x => x.Name_L1); 
      Map(x => x.Name_L2); 
      HasMany(x => x.Children).KeyColumn("id_SysPermissionTree_Parent").AsSet(); 
      HasMany(x => x.Permissions).KeyColumn("id_SysPermissionTree").AsSet(); 
     } 
    } 
} 

Ve kullandığım sorgusu şuydu: Ben veritabanına tek isabet ile bir ağaç yapısı yüklemek istediğinde

ben buldum .JoinType.LeftOuterJoin. Çünkü InnerJoin kullansaydım, yapı sadece bir sorguyla yüklenmedi. LeftOuterJoin'i kullanmam gerekti, böylece NHibernate varlıkları tanıdı. idam

SQL Sorguları idi:

İlk sorgu dış bırakılır
SELECT this_.ID as ID28_2_, this_.Name_L1 as Name2_28_2_, this_.Name_L2 as Name3_28_2_, this_.id_SysPermissionTree_Parent as id4_28_2_, t1_.id_SysPermissionTree_Parent as id4_4_, t1_.ID as ID4_, t1_.ID as ID28_0_, t1_.Name_L1 as Name2_28_0_, t1_.Name_L2 as Name3_28_0_, t1_.id_SysPermissionTree_Parent as id4_28_0_, p2_.id_SysPermissionTree as id4_5_, p2_.ID as ID5_, p2_.ID as ID27_1_, p2_.Name_L1 as Name2_27_1_, p2_.Name_L2 as Name3_27_1_, p2_.id_SysPermissionTree as id4_27_1_ FROM [SysPermissionTree] this_ left outer join [SysPermissionTree] t1_ on this_.ID=t1_.id_SysPermissionTree_Parent left outer join [SysPermission] p2_ on t1_.ID=p2_.id_SysPermissionTree WHERE this_.id_SysPermissionTree_Parent is null 
SELECT this_.ID as ID28_2_, this_.Name_L1 as Name2_28_2_, this_.Name_L2 as Name3_28_2_, this_.id_SysPermissionTree_Parent as id4_28_2_, t1_.ID as ID28_0_, t1_.Name_L1 as Name2_28_0_, t1_.Name_L2 as Name3_28_0_, t1_.id_SysPermissionTree_Parent as id4_28_0_, p2_.ID as ID27_1_, p2_.Name_L1 as Name2_27_1_, p2_.Name_L2 as Name3_27_1_, p2_.id_SysPermissionTree as id4_27_1_ FROM [SysPermissionTree] this_ inner join [SysPermissionTree] t1_ on this_.ID=t1_.id_SysPermissionTree_Parent inner join [SysPermission] p2_ on t1_.ID=p2_.id_SysPermissionTree WHERE this_.id_SysPermissionTree_Parent is null 

katılmak ve biz 2 ekstra alan almak: t1_.id_SysPermissionTree_Parent id4_4_ olarak, t1_.ID ID4_

olarak Yani ne Söylemeye çalışıyorum ki, eğer NHibernate kullanırsanız, dış birleşim, bazen NHibernate'in iç işleyişine uymak zorundadır.

İlgili konular