我有这样的域结构(例如,伪代码):
this.get('user.following').forEach((followerId)=>
{
this.store.findRecord('user', followerId)
.then((user) => {
console.log('resolved follower ',user.get('name'));
publishers.pushObject(user._internalModel);
})
.catch((e) => {
console.error('publisher catch', e);
});
});
每个系列都很懒惰。 我想知道当我以懒惰的方式访问Shelf's Books财产时,是否有办法获取房间的所有书籍(没有子选择)。
当我获得Room时,nhibernate只获取空间(class Room
{
Id: long
Shelves: list of Shelf
}
class Shelf
{
Id: long
Room: Room class (room_id column)
Books: list of Book
}
class Book
{
Id: long (id column)
Shelf: Shelf class (shelf_id column)
Room: Room class (room_id column)
Title: string (title column)
}
),当我访问Shelves属性时,nhibernate获取此房间的所有书架(select * from rooms r where ...
),当我访问Books属性时它会加载书籍唯一一个架子(一般来说是正常的),但是......
在我的情况下,如果我访问Book,我很可能会与这个房间的其他书籍一起工作,所以如果我触摸书籍,我想预先加载这个房间的所有书籍并将它们放在他们的书架上。
nhibernate最接近的特征是select * from shelves s where s.room_id = X
。但是在我的案例中有不必要的选择,因为我可以通过room_id获取此房间的书籍:fetch='subselect'
。
有办法做到这一点吗?
谢谢!
答案 0 :(得分:1)
NHibernate内置的本地方式称为Batch Fetching:
NHibernate可以有效地使用批量提取,也就是说,如果访问一个代理(或集合),NHibernate可以加载几个未初始化的代理。批量提取是懒惰选择提取策略的优化。有两种方法可以调整批处理获取:在类和集合级别上。
更多细节(上面的文档链接除外)可以在这里找到:
答案 1 :(得分:0)
我找到了更优雅的解决方案。事实证明我可以为包/地图定义sql-query ...
看起来像:
<hibernate-mapping...>
<class name="Shelf">
<many-to-one name="Room" column="room_id"... />
<bag name="Books">
...
<loader query-ref="ShelvesQuery" />
</bag>
</class>
<sql-query name="ShelvesQuery">
<load-collection alias="book" role="Shelf.Books" />
<![CDATA[
select b.id
b.room_id,
b.shelf_id,
b.title
from books b
where b.room_id = :room_id
]]>
</sql-query>
</hibernate-mapping>
它就像一个魅力!