NHibernate 特定映射(“使用祖父母选择”)

Posted

技术标签:

【中文标题】NHibernate 特定映射(“使用祖父母选择”)【英文标题】:NHibernate specific mapping ("select using grand-parent") 【发布时间】:2015-11-04 18:01:52 【问题描述】:

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

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)

每个集合都是惰性的。 我想知道当我以惰性方式访问 Shelf's Books 属性时,是否有办法获取房间的所有书籍(没有子选择)。

当我得到 Room 时,nhibernate 只获取房间 (select * from rooms r where ...),当我访问 Shelves 属性时,nhibernate 获取这个房间的所有书架 (select * from shelves s where s.room_id = X),当我访问 Books 属性时,它为唯一一个书架加载书籍(一般情况下是正常的),但是......

在我的情况下,如果我访问 Book,我很有可能也会与这个房间的其他书籍一起工作,所以如果我触摸 book,我想预加载这个房间的所有书籍并将它们放在他们的书架上。

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

有没有办法做到这一点?

谢谢!

【问题讨论】:

【参考方案1】:

NHibernate 内置的原生方式称为 Batch Fetching:

19.1.5. Using batch fetching

NHibernate 可以有效地利用批量获取,也就是说,如果访问一个代理(或集合),NHibernate 可以加载多个未初始化的代理。批量获取是对惰性选择获取策略的优化。有两种方法可以调整批量获取:在类和集合级别。

更多细节(上面的文档链接除外)可以在这里找到:

How to Eager Load Associations without duplication in NHibernate? NHibernate Fetch/FetchMany duplication in resultset, how to fix with ToFuture() How to eager load objects in a list/collection?

【讨论】:

【参考方案2】:

我找到了一个更优雅的解决方案。事实证明我可以为包/地图定义 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>

它就像一个魅力!

【讨论】:

以上是关于NHibernate 特定映射(“使用祖父母选择”)的主要内容,如果未能解决你的问题,请参考以下文章

如何查询 NHibernate 的特定类型?

NHibernate 是不是支持使用复合 ID 将抽象类映射到不同的表?

Fluent NHibernate 复合映射 <long, string>

NHibernate:在更新/删除/插入视图上映射的类时是否可以使用存储过程?

ABP官方文档翻译 9.3 NHibernate集成

NHibernate:映射具有属性的复杂值类型?