在 nhibernate 中加载复杂图形

Loading complex graph in nhibernate

想象一下,我有一个非常复杂的模型图,例如:

Orchestra -> Musicians -> Instruments -> Properties
                                      -> Items
                       -> Songs -> Parts

理论上我知道 Futures 是如何工作的,但是我如何加载这个完整的图表让我说一个具体的音乐家(由 id 指定)。

我知道对于同一级别的每个 collection 我必须创建一个简单的未来查询以避免同一查询中的笛卡尔积。 所以当我执行这样的代码时:

using(var session = GetSession()){
    var instrumentQuery = session.QueryOver<Musicians>()
         .Where(x=>x.Id == CONCRETEMUSICIANIDTHERE)
         .JoinQueryOver<Instruments>(x=>x.Instruments)                     
         .Future();
    var instrumentProperties = = session.QueryOver<Musicians>()
         .Where(x=>x.Id == CONCRETEMUSICIANIDTHERE)
         .JoinQueryOver<Instrument>(x=>x.Instruments, ()=> instrumentAlias)
         .JoinQueryOver<Property>(()=>instrumentAlias.Properties)
         .Future();
     var instrumentItems = = session.QueryOver<Musicians>()
         .Where(x=>x.Id == CONCRETEMUSICIANIDTHERE)
         .JoinQueryOver<Instrument>(x=>x.Instruments, ()=> instrumentAlias)
         .JoinQueryOver<Item>(()=>instrumentAlias.Items)
         .Future();
    ...
    ...CONTINUE same future queries for each unique collection       
    ...

    ...
    var result = session.QueryOver<Musician>()
         .Where(x=>x.Id == CONCRETEMUSICIANIDTHERE)
         .SingleOrDefault<Musician>(); //This query is not future so it should???? load all futures ???

    return result;

}

但即使最后一个查询不是未来的,它也不会将那些 FUTUR..ISH 查询发送到数据库(我用 SQL 分析器检查过......没有这样的 SQL 标题到数据库)

musician.instrument 仍然抛出惰性初始化异常。

此代码只是演示性的,纯理论性的。

我要避免的是:

我想要达到的目标

还有一个类似的问题: How to load a large, complex object graph using NHibernate

答案是……改变你的映射……我不想要,因为我看不到为每次使用转换加载这个复杂图形的点(即使是简单的转换)

技术背景:

我会说,这里的方式是

  • 使用 Fetch 而不是 JoinQuery
  • 最终结果也放入Future

所以这将是更新后的代码段:

var instrumentQuery = session.QueryOver<Musicians>()
     .Where(x=>x.Id == CONCRETEMUSICIANIDTHERE)
     .Fetch(x=>x.Instruments).Eager
     .Future();
var instrumentProperties = = session.QueryOver<Musicians>()
     .Where(x=>x.Id == CONCRETEMUSICIANIDTHERE)
     .Fetch(x=>x.SecondCollection).Eager
     .Future();

...
...CONTINUE same future queries for each unique collection       
...

...
var result = session.QueryOver<Musician>()
     .Where(x=>x.Id == CONCRETEMUSICIANIDTHERE)
     // all will be fetaures
     .Future()
     .SingleOrDefault<Musician>();

注意:我会采取不同的方式。仅加载根对象(音乐家)。使用 batch-size 优化抓取。在会话打开时创建 DTO。