자 NHibernate는 내부 않는 경우 부모 테이블에서 아이 ID에서 ID를하지 않습니다 (하지만 그들은 같은 것)에 가입.
예 :
TableParent (ID, Name)
TableChild (ID, ID_TableParent, ....)
nHibernate 수는 내부 조인 않는 경우, 당신은 얻을 : nHibernate 수는 왼쪽 외부 조인 않는 경우
는
select c.ID, c.ID_TableParent, p.Name
from TableChild c
inner join TableParent p on p.ID = c.ID_TableParent
, 당신은 얻을 :
select c.ID, c.ID_TableParent, p.ID, p.Name
from TableChild c
left outer join TableParent p on p.ID = c.ID_TableParent
때문에를 Hibernate의 내부 동작 중 두 번째 질의로부터 2 개의 엔티티를 생성 할 수있다. TableChild 및 TableParent에 대한 하나의 엔터티.
첫 번째 쿼리에서는 TableChild 엔티티 만 가져오고 어떤 경우에는 p.Name이 무시되고 (두 번째 수준에서 probalby) TableParent를 참조하는 속성을 검사 할 때 데이터베이스가 다시 쿼리됩니다. NHibernate.SqlCommand으로
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();
}
}
}
그리고 내가 사용하는 쿼리이 있었다 : 나는 데이터베이스에 하나 개의 히트와 함께 트리 구조를로드하고 싶어 할 때
나는 밖으로 이걸 발견 .JoinType.LeftOuterJoin. 왜냐하면 InnerJoin을 사용하면 구조가 하나의 쿼리만으로로드되지 않기 때문입니다. NHibernate가 엔티티를 인식하도록 LeftOuterJoin을 사용해야했습니다. 실행
SQL 쿼리했다 :
가 첫 번째 쿼리가 외부를 남겨
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
가입하고 우리가이 개 추가 필드를 얻을 : t1_.id_SysPermissionTree_Parent를 id4_4_로, t1_.ID을 ID4_
그래서 내가 당신에게 말하려고하면 NHibernate를 사용한다면 왼쪽 외부 조인은 때때로 NHibernate의 내부 동작을 따라야 만하는 것입니다.
쿼리는 어떻게 생겼습니까? HQL이나 기준을 사용하고 있습니까? –
난 그냥 엔터티를 수행합니다. 가져 오기, 내가 너무 똑같은 문제와 HQL 테스트 btw. – ksang
나는 수정 된 nhibernate 소스에 의해이 문제를 해결했다. nhibernate가 첫 번째 레벨의 join을 위해서만 innerjoint sql을 생성한다는 것을 알았다. 어쩌면 누군가가 왜 그런 식으로 행동하는지 말할 수 있습니다. – ksang