项目中的两个对象 A, B, 采用了 one-to-one 映射进行关联。
(原文链接 http://ddbiz.com/?p=216)
因为对象中有一个大字段,每次存取都会耗费大量查询,因此把此内容分开存放在 B 对象中。
<class name="A">
<id name="Id" column="Id" type="Int32" unsaved-value="-1">
<generator class="native" />
</id>
<one-to-one name="B" cascade="all" />
</class>
<class name="B">
<id name="Id" column="Id" type="Int32" unsaved-value="-1">
<generator class="foreign" >
<param name="property">A</param>
</generator>
</id>
<one-to-one name="A" constrained="true" cascade="all" />
</class>
在使用 ICriteria c = sessionManager.OpenSession().CreateCriteria(typeof(A)) 的查询时
c.List()
返回了 IList<object[A][B])的对象数组,与预期的相反,因为我们只想取A对象。查看 NHibernate.SQL,发现此查询语句采用了 A outer join B
从而返回全部对象。
这种方式采用一次查询返回对象的两个部分,执行效率确实会提高,但是不适合此处我们的应用,因为B部分的大内容我们此时用不到。可以采用如下几种方式来定义仅仅返回对象A:
- 1 全局限定 one-to-one, many-to-one
hibernate.max_fetch_depth
= 0:不通过 outer join 装载对象
> 0:使用outer join 同时装载对象
hibernate.use_outer_join = true|false
此属性仅作版本保留,请使用 max_fetch_depth 设置
- 2 在 mapping 文件中限定
<class name="A">
<id name="Id" column="Id" type="Int32" unsaved-value="-1">
<generator class="native" />
</id>
<one-to-one name="B" cascade="all" outer-join="false" />
</class>
<one-to-one ...outer-join="auto|true|false"/>
3 在 mapping 文件中限定 fetch 方法
<class name="A">
<id name="Id" column="Id" type="Int32" unsaved-value="-1">
<generator class="native" />
</id>
<one-to-one name="B" cascade="all" fetch="select" />
</class>
<one-to-one ... fetch="join|select"/>