在NHibernate中加载复杂图 [英] Loading complex graph in nhibernate

查看:102
本文介绍了在NHibernate中加载复杂图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Imagina i have pretty complex model graph such as for an example:

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

理论上,我知道期货的运作方式,但是我如何加载完整的图表,可以让具体的音乐家(由id指定)说

I know in theory how Futures works but how do i load this complete graph lets say for a concrete musician (specified by id).

我知道,对于同一级别的每个集合,我都必须创建一个简单的将来查询,以避免在同一查询中使用笛卡尔积. 所以当我执行这样的代码时:

I know that for each collection on same level i have to create simple one future query to avoid Cartesian product in same query. so when i execute code like this:

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标题发送到数据库)

But even when the last query is NOT future it wont send those FUTUR..ISH queries to DB ( i checked with SQL profiler... there is no such SQL heading to DB)

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

musician.instrument still throws lazy initialization exception.

此代码仅是说明性的,并且仅是理论上的.

This code is only demostrative and purely theoretical.

我要避免的是:

  • 使用HQL(我讨厌那些魔术弦...)
  • 更改映射以热切地加载所有内容,因为在某些用例中,我只需要音乐家和乐器? (或任何其他子集)
  • 在这里避免N + 1个查询问题
  • 将会话保持打开状态的时间过长,因为这些数据可能会与其他服务器实例发生变化

我想实现的目标

  • 要么强制休眠,要么根据提供的标准恰当地创建和构造对象结构.

  • 强制nhibernate仅对此查询使用访存选择

还有一个类似的问题: 如何使用NHibernate加载大型,复杂的对象图

there is also simmilar question: How to load a large, complex object graph using NHibernate

答案是...更改您的映射...我不想要,因为我看不到每次使用强制转换(甚至是简单使用)都加载此复杂图形的要点

and the answer is... Change your mappings... which i dont want because i dont see a point to load this complex graph for each use cast (even the simple ones)

技术背景:

  • 我们使用Nhibernate 4.0
  • 作为数据库,可能会使用Azure数据库或SQL Server(或也许使用postgreSQL)

推荐答案

我会说,这里的方式是

  • 使用Fetch代替 JoinQuery
  • 也将最终结果放入Future
  • to use Fetch instead of JoinQuery and
  • place final result into Future as well

这将是更新的代码段:

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>();

注意:我会采取不同的方式.仅加载根对象(音乐家).使用批量大小进行优化抓取.会话打开时创建DTO.

NOTE: I would go different way. Load just root object (Musician). Use batch-size for optimized fetching. Create DTO while session is open.

这篇关于在NHibernate中加载复杂图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆