我的课程Unit
的{{1}}为Dictionary
。映射看起来像这样
Parts
当我<class name="Unit" table="Units">
<id name="Id">
<generator class="native"/>
</id>
<property name="CreationDate" />
<property name="MacAddress" />
<property name="OEMId" />
<property name="SerialNumber" />
<property name="QualityControlState" />
<map name="Parts" table="UnitParts" lazy="false">
<key column="UnitId"/>
<index column="TypeOfPart" type="integer"/>
<composite-element class="UnitPart">
<property name="PartInfo"/>
<property name="Remarks"/>
</composite-element>
</map>
一切顺利时:两个表格中都填充了正确的数据。并且该单元也可以使用Session.SaveOrUpdate(Unit)
进行转换(所有Parts
)。
问题:获取多个单元延迟加载Session.Get(typeof(Unit)
Parts
。
伪代码中重述的问题:Dictionary
以下代码让我感到困惑。当我使用调试器逐步执行它时,LoadMethodOfPartsDictionary = (Stepping with Debugger) ? Eagerly : Lazy;
的{{1}} Parts
被急切加载。但当我跑到Dictionary
(而不是单步执行Unit
)时,似乎NHibernate想要延迟加载,因为return Units
Units = crit.Future<Unit>().ToList<Unit>();
突然变为Parts
。
Dictionary
任何提示都表示赞赏。
P.S。我使用了[Debugging]标签,因为这似乎是这种情况下的关键。
答案 0 :(得分:2)
如何从数据库接收数据有两个不同的概念。如果是一对多(列表,词典)。
1)我们可以通过ID或引用(类似情况)调用NHibernate获取数据
session.Get<Unit>(1);
在这种情况下,NHibernates会注入标记为 lazy 的所有 属性。因此,在您的情况下,这将导致急切地加载零件。
相似的是public virtual Unit Unit { get; set; }
OtherObject
var otherObject = ... // get from session
var unit = otherObject.Unit; // the full Unit with all `Lazy="false"` properties is loaded
2)但我们也可以使用Criteria
(如你的情况)。但是,这是不同的方法。在这种情况下,我们明确表示我们只希望使用Unit
Units = crit.Future<Unit>().ToList<Unit>();
这有很多好处:
Unit
表但如果真的需要(关于副作用的问题,如inocrrect分页)我们也可以在一个选择中加载部件:
Units = crit
.SetFetchMode("Parts", FetchMode.Eager)
.Future<Unit>()
.ToList<Unit>();
现在已经全部填充了。
3)我投票的方法(我使用100%)是让收集变得懒惰,并分配batch-size
19.1.5. Using batch fetching
EXTENDED
向您展示如何更改映射:
<map name="Parts" table="UnitParts" lazy="true" batch-size="25">
从那时起,你的Util很轻巧。没有零件加载,直到真正需要。如果在整个请求期间打开会话,一旦触摸了部件,它们将被加载到一个SELECT中(如果Utils的页面大小不大于25)
这种方法非常有效,因为它使用了ORM的强大功能 - 一切都很懒散