C# 在nhibernate中加载复数图
Imagina我有非常复杂的模型图,例如:C# 在nhibernate中加载复数图,c#,nhibernate,future,C#,Nhibernate,Future,Imagina我有非常复杂的模型图,例如: Orchestra -> Musicians -> Instruments -> Properties -> Items -> Songs -> Parts 我在理论上知道未来是如何运作的,但我如何加载这个完整的图表,比如说对于一个具体的音乐家(由id指定) 我知道,对于同一级别上的每个集合,我
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)
- 使用
而不是JoinQuery和Fetch
- 将最终结果放入
中未来
- 我想说,这里的方式是
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。这只是关于服务内部工作和实体更改。然后,我试图展示的内容将起作用。创建尽可能多的学院,渴望未来。然后把根实体也放进未来并触摸它。所有将在一次射击中加载。。。谢谢,有点奇怪,当你执行正常的查询时,期货并没有受到影响。我将把这标记为一个答案。