好的,我为自己写了一个例子来反映你的结构,这应该可以工作:
int projectId = 1; // replace that with the id you want
// required for the joins in QueryOver
Project pAlias = null;
Partner paAlias = null;
PartnerCosts pcAlias = null;
Address aAlias = null;
Money mAlias = null;
// Query to load the desired project and nothing else
var projects = repo.Session.QueryOver<Project>(() => pAlias)
.Where(p => p.Id == projectId)
.Future<Project>();
// Query to load the Partners with the Costs (and the Money)
var partners = repo.Session.QueryOver<Partner>(() => paAlias)
.JoinAlias(p => p.Project, () => pAlias)
.Left.JoinAlias(() => paAlias.Costs, () => pcAlias)
.JoinAlias(() => pcAlias.Money, () => mAlias)
.Where(() => pAlias.Id == projectId)
.Future<Partner>();
// Query to load the Partners with the Addresses
var partners2 = repo.Session.QueryOver<Partner>(() => paAlias)
.JoinAlias(o => o.Project, () => pAlias)
.Left.JoinAlias(() => paAlias.Addresses, () => aAlias)
.Where(() => pAlias.Id == projectId)
.Future<Partner>();
// when this is executed, the three queries are executed in one roundtrip
var list = projects.ToList();
Project project = list.FirstOrDefault();
我的类有不同的名称,但反映了完全相同的结构。我替换了名字,希望没有错别字。
解释:
连接需要别名。我定义了三个查询来加载Project
你想要的,Partners
with theirCosts
和 the Partners
with their Addresses
。通过使用,.Futures()
我基本上告诉 NHibernate 在我真正想要结果的那一刻在一次往返中执行它们,使用projects.ToList()
.
这将导致三个 SQL 语句确实在一次往返中执行。这三个语句将返回以下结果:1) 1 行包含您的项目 2) x 行包含合作伙伴及其成本(和资金),其中 x 是项目合作伙伴的成本总数 3) y 行包含合作伙伴及其地址,其中 y 是项目合作伙伴的地址总数
您的数据库应该返回 1+x+y 行,而不是 x*y 行,这将是一个笛卡尔积。我确实希望您的数据库实际上支持该功能。