NHibernate 特定映射 ("select using grand-parent")

NHibernate specific mapping ("select using grand-parent")

我有这样的域结构(例子,伪代码):

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)
}

每个collection都是懒惰的。 我想知道当我以懒惰的方式访问书架的书籍 属性 时,有没有办法获取房间的所有书籍(没有子 select)。

当我获得 Room 时,nhibernate 仅获取房间 (select * from rooms r where ...),当我访问 Shelves 属性,nhibernate 获取该房间的所有货架 (select * from shelves s where s.room_id = X),当我访问书籍 属性 它加载了唯一一个书架的书籍(通常是正常的),但是...

在我的例子中,如果我访问 Book,我很可能也会使用这个房间的其他书籍,所以如果我触摸 Book,我想预加载这个房间的所有书籍并将它们放在他们的书架上。

nhibernate 最接近的特性是fetch='subselect'。但是在我的情况下没有必要的 select 因为我可以通过 room_id: select * from books b where b.room_id = x 为这个房间取书。

有办法吗?

谢谢!

内置于 NHibernate 中的本机方式称为批量获取:

19.1.5. Using batch fetching

NHibernate can make efficient use of batch fetching, that is, NHibernate can load several uninitialized proxies if one proxy is accessed (or collections. Batch fetching is an optimization of the lazy select fetching strategy. There are two ways you can tune batch fetching: on the class and the collection level.

更多详细信息(除了上面的文档 link)可以在这里找到:

  • How to Eager Load Associations without duplication in NHibernate?

我找到了一个更优雅的解决方案。事实证明我可以为 bag/map...

定义 sql-查询

看起来像:

<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>

它很有魅力!