nhibernate在多对一实体上生成左外部联接
我使用的是nHibernate 2.1.2,并且重新认识到nHibernate将在嵌套的多对一实体上生成左外部联接。似乎从实体组织开始,在第三个嵌套注释上开始生成左外部联接。我在映射文件中设置了以下强制使用内部联接,映射文件中是否有遗漏的内容?真希望有人能给我一个提示。感谢您的帮助nhibernate在多对一实体上生成左外部联接,nhibernate,outer-join,Nhibernate,Outer Join,我使用的是nHibernate 2.1.2,并且重新认识到nHibernate将在嵌套的多对一实体上生成左外部联接。似乎从实体组织开始,在第三个嵌套注释上开始生成左外部联接。我在映射文件中设置了以下强制使用内部联接,映射文件中是否有遗漏的内容?真希望有人能给我一个提示。感谢您的帮助 lazy="false" fetch="join" 实体和关系示例: 销售记录-员工-组织 nhibernate生成: select... from sales inner join employee left
lazy="false" fetch="join"
实体和关系示例:
销售记录-员工-组织
nhibernate生成:
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>
<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>
Employee.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>
<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>
如果NHibernate执行内部联接,则您不需要从子表获取ID,也不需要从父表获取ID(但它们是相同的) 例如:
TableParent (ID, Name)
TableChild (ID, ID_TableParent, ....)
如果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
如果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
由于NHibernate的内部工作原理,它可以从第二个查询中创建两个实体。一个实体用于TableChild,一个实体用于TableParent
在第一个查询中,您只能得到TableChild实体,在某些情况下,p.Name将被忽略(可能是在第二个级别),并且它将在检查引用TableParent的属性时重新查询数据库
当我想加载一个只对数据库进行一次点击的树结构时,我发现了这一点:
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();
}
}
}
其中第一个查询是外部联接,我们得到两个额外的字段:t1_u.id_SysPermissionTree_Parent作为id4_4,t1_u.id作为id4_
所以我想告诉你的是,如果你使用NHibernate,那么左外连接有时必须符合NHibernate的内部工作方式。查询是什么样子的?您使用的是HQL还是标准?我只使用Entity.Fetch,顺便说一句,我也使用HQL测试了同样的问题。我已经通过修改nhibernate源代码解决了这个问题,我发现nhibernate只会为第一级连接生成innerjoint sql。也许有人能告诉我为什么它会这样。