Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/nhibernate/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
nhibernate在多对一实体上生成左外部联接_Nhibernate_Outer Join - Fatal编程技术网

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

我使用的是nHibernate 2.1.2,并且重新认识到nHibernate将在嵌套的多对一实体上生成左外部联接。似乎从实体组织开始,在第三个嵌套注释上开始生成左外部联接。我在映射文件中设置了以下强制使用内部联接,映射文件中是否有遗漏的内容?真希望有人能给我一个提示。感谢您的帮助

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。也许有人能告诉我为什么它会这样。