C# 在nhibernate中加载复数图

C# 在nhibernate中加载复数图,c#,nhibernate,future,C#,Nhibernate,Future,Imagina我有非常复杂的模型图,例如: Orchestra -> Musicians -> Instruments -> Properties -> Items -> Songs -> Parts 我在理论上知道未来是如何运作的,但我如何加载这个完整的图表,比如说对于一个具体的音乐家(由id指定) 我知道,对于同一级别上的每个集合,我

Imagina我有非常复杂的模型图,例如:

Orchestra -> Musicians -> Instruments -> Properties
                                      -> Items
                       -> Songs -> Parts
我在理论上知道未来是如何运作的,但我如何加载这个完整的图表,比如说对于一个具体的音乐家(由id指定)

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

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;

}
使用(var session=GetSession()){
var instrumentQuery=session.QueryOver()
.Where(x=>x.Id==CONCRETEMUSICIANIDTHERE)
.JoinQueryOver(x=>x.Instruments)
.Future();
var instrumentProperties==session.QueryOver()
.Where(x=>x.Id==CONCRETEMUSICIANIDTHERE)
.JoinQueryOver(x=>x.Instruments,()=>instrumentAlias)
.JoinQueryOver(()=>instrumentAlias.Properties)
.Future();
var instrumentItems==session.QueryOver()
.Where(x=>x.Id==CONCRETEMUSICIANIDTHERE)
.JoinQueryOver(x=>x.Instruments,()=>instrumentAlias)
.JoinQueryOver(()=>instrumentAlias.Items)
.Future();
...
…继续对每个唯一集合进行相同的未来查询
...
...
var result=session.QueryOver()
.Where(x=>x.Id==CONCRETEMUSICIANIDTHERE)
.SingleOrDefault();//此查询不是未来查询,因此应该加载所有未来查询???
返回结果;
}
但即使最后一个查询不是future,它也不会将这些FUTUR..ISH查询发送到DB(我用SQL profiler检查过了…DB没有这样的SQL标题)

Musitor.instrument仍引发延迟初始化异常

本准则仅为示范性的,纯理论性的

我想避免的是:

  • 使用HQL(我讨厌那些神奇的字符串…)
  • 更改映射以加载所有内容,因为有些用例我只需要音乐家和仪器?(或任何其他子集)
  • 在此避免N+1查询问题
  • 将会话保持打开状态的时间过长,因为这些数据可能会从其他服务器实例更改
我想要实现的目标

  • 或者强制nhibernate根据提供的条件正确创建和构造对象结构

  • 强制nhibernate仅对此查询使用fetch select
还有一个相似的问题:

答案是。。。更改映射。。。我不想这样,因为我看不到为每次使用强制转换加载这个复杂图形的点(即使是简单的)

技术背景:

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

    • 我想说,这里的方式是

      • 使用
        Fetch
        而不是JoinQuery和
      • 最终结果放入
        未来
      这就是更新后的代码段:

      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>();
      
      var-instrumentQuery=session.QueryOver()
      .Where(x=>x.Id==CONCRETEMUSICIANIDTHERE)
      .Fetch(x=>x.Instruments)。急切
      .Future();
      var instrumentProperties==session.QueryOver()
      .Where(x=>x.Id==CONCRETEMUSICIANIDTHERE)
      .Fetch(x=>x.SecondCollection)
      .Future();
      ...
      …继续对每个唯一集合进行相同的未来查询
      ...
      ...
      var result=session.QueryOver()
      .Where(x=>x.Id==CONCRETEMUSICIANIDTHERE)
      //一切都将是费托雷斯
      .Future()
      .SingleOrDefault();
      

      注:我会走不同的路。仅加载根对象(音乐家)。用于优化抓取。会话打开时创建DTO。

      您确定吗。。。。。。Fetch(x=>x.Instruments,()=>InstrumentAlias).Eager.Fetch(()=>InstrumentAlias.Properties).Eager…..这不会在仪器和属性上创建笛卡尔积吗?一般来说:我肯定,我决不会这样做。我会懒洋洋地加载所有内容(参见我的链接),并创建DTO或序列化对象。没有显式抓取。只需
      批量抓取
      ,以避免1+N。对于您的问题:-我测试的上述示例…可能。。。可能只有一个对象以这种方式获取。。。所以我更新了问题。它应该显示的内容:我们可以为所有学院使用
      Fetch
      eager和
      Future
      。。。和根实体的
      SingleOrDefault
      Future
      。但我会使用
      批量抓取
      是的,但我真的很想在一次查询中将我需要的一切(只需要我需要的)加载到数据库中,因为数据可能是非常活跃和变化的。。。。这意味着我必须设置相当大的isolationMode,可以序列化到对数据库有高性能影响的会话。在这种情况下,我们也没有DTO。这只是关于服务内部工作和实体更改。然后,我试图展示的内容将起作用。创建尽可能多的学院,渴望未来。然后把根实体也放进未来并触摸它。所有将在一次射击中加载。。。谢谢,有点奇怪,当你执行正常的查询时,期货并没有受到影响。我将把这标记为一个答案。