nhibernate 在多对一实体上生成左外连接
我正在使用 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>
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>
i'm using nHibernate 2.1.2 and relized that nhibernate will generate left outer join on nested many-to-one entities. it seems start generate left-outer-join on 3rd nested note onwards which start from entity Organization. i have set following in the mapping file to force use inner-join, has anything i missed out in the mapping file? really hope somebody could give me a hint on this. appreciate any helps!
lazy="false" fetch="join"
Example Entites and Relationships:
Sales Record - Employee - Organization
nhibernate generate:
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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果 NHibernate 执行内部联接,则您不会从子表中获取 ID,也不会从父表中获取 ID(但它们是相同的)。
示例:
如果 nHibernate 执行内连接,您将得到:
如果 nHibernate 执行左外连接,您将得到:
由于 NHibernate 的内部工作原理,它可以从第二个查询创建 2 个实体。一个实体用于 TableChild,一个实体用于 TableParent。
在第一个查询中,您只会获得 TableChild 实体,在某些情况下,p.Name 将被忽略(可能在第二级),并且它将在检查引用 TableParent 的属性时重新查询数据库。
当我想加载一个只需要一次数据库命中的树结构时,我发现了这一点:
我使用的查询是这样的:
With NHibernate.SqlCommand.JoinType.LeftOuterJoin。因为如果我使用 InnerJoin,结构不会仅通过一个查询加载。我必须使用 LeftOuterJoin,以便 NHibernate 识别这些实体。
执行的 SQL 查询是:
第一个查询是左外连接,我们得到 2 个额外字段:t1_.id_SysPermissionTree_Parent as id4_4_,t1_.ID as ID4_
所以我想告诉你的是,如果你使用 NHibernate 那么左外连接有时,为了遵守 NHibernate 的内部运作方式,join 是必须的。
If NHibernate does an inner join you don't ID from a child and ID from a parent table (but they're the same).
Example:
If nHibernate does an inner join, you get:
If nHibernate does an left outer join, you get:
And because of the inner workings of NHibernate it can then create 2 entities from the second query. One entity for TableChild and one for TableParent.
In the first query you'd only get TableChild entity and in some cases the p.Name would be ignored (probalby on the second level) and it would requery the database on checking the property that references TableParent.
I found out this when I wanted to load a tree structure with only one hit to the database:
And the query I used was this:
With NHibernate.SqlCommand.JoinType.LeftOuterJoin. Because if I used InnerJoin the structure didn't load with only one query. I had to use LeftOuterJoin, so that NHibernate recognized the entities.
SQL Queries that executed were:
where the first query is left outer join and we get 2 extra fields: t1_.id_SysPermissionTree_Parent as id4_4_, t1_.ID as ID4_
So what I'm trying to tell you is that if you use NHibernate then left outer join is sometimes a must to comply with inner workings of NHibernate.