【发布时间】:2015-02-27 04:52:32
【问题描述】:
想象一下,我有非常复杂的模型图,例如:
Orchestra -> Musicians -> Instruments -> Properties
-> Items
-> Songs -> Parts
我理论上知道 Futures 是如何工作的,但是我如何加载这个完整的图表让我们说一个具体的音乐家(由 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;
}
但即使最后一个查询不是将来的,它也不会将那些 FUTUR..ISH 查询发送到 DB(我用 SQL 分析器检查过......没有这样的 SQL 标题到 DB)
musician.instrument 仍然抛出延迟初始化异常。
此代码仅是演示性的,纯属理论性的。
我要避免的是:
- 使用 HQL(我讨厌那些神奇的字符串...)
- 更改映射以急切地加载所有内容,因为有些用例我只需要音乐家和乐器? (或任何其他子集)
- 在这里避免 N+1 查询问题
- 让会话打开太久,因为这些数据可能会从其他服务器实例更改
我想要达到的目标
- 强制 nhibernate 根据提供的标准正确地创建和构造对象结构。
或
- 强制 nhibernate 仅对此查询使用 fetch select
还有一个类似的问题: How to load a large, complex object graph using NHibernate
答案是……改变你的映射……这是我不想要的,因为我看不到为每次使用转换加载这个复杂图表的点(即使是简单的)
技术背景:
- 我们使用 Nhibernate 4.0
- 作为数据库,可能会使用 Azure DB 或 SQL Server(或者可能是 postgreSQL)
【问题讨论】:
标签: c# nhibernate future