NHibernate 3。“替代方案”;然后,取;在QueryOver

NHibernate 3。“替代方案”;然后,取;在QueryOver,nhibernate,linq-to-nhibernate,queryover,Nhibernate,Linq To Nhibernate,Queryover,我将NHibernate 3.0与LINQ提供程序和QueryOver一起使用。有时,我希望加载相关数据,而在LINQ和QueryOver中,都有“Fetch”方法。现在我有一个特殊的场景,我希望不直接在第二层加载属性,例如: Foo f = ...; f.A.B.C 使用LINQ没有问题,因为您可以使用“ThenFetch”方法“链接”获取,如: var result=Session.Query(); 在QueryOver中没有这样的方法,那么如何才能获得相同的结果呢 提前谢谢。我想你可以

我将NHibernate 3.0与LINQ提供程序和QueryOver一起使用。有时,我希望加载相关数据,而在LINQ和QueryOver中,都有“Fetch”方法。现在我有一个特殊的场景,我希望不直接在第二层加载属性,例如:

Foo f = ...;
f.A.B.C
使用LINQ没有问题,因为您可以使用“ThenFetch”方法“链接”获取,如:

var result=Session.Query();
在QueryOver中没有这样的方法,那么如何才能获得相同的结果呢


提前谢谢。

我想你可以用JoinQueryOver做到这一点

IQueryOver<Relation> actual =
   CreateTestQueryOver<Relation>()
    .Inner.JoinQueryOver(r => r.Related1)
    .Left.JoinQueryOver(r => r.Related2)
    .Right.JoinQueryOver(r => r.Related3)
    .Full.JoinQueryOver(r => r.Related4)
    .JoinQueryOver(r => r.Collection1, () => collection1Alias)
    .Left.JoinQueryOver(r => r.Collection2, () => collection2Alias)
    .Right.JoinQueryOver(r => r.Collection3)
    .Full.JoinQueryOver(r => r.People, () => personAlias); 
IQueryOver实际=
CreateTestQueryOver()
.internal.JoinQueryOver(r=>r.Related1)
.Left.JoinQueryOver(r=>r.Related2)
.Right.JoinQueryOver(r=>r.Related3)
.Full.JoinQueryOver(r=>r.Related4)
.JoinQueryOver(r=>r.Collection1,()=>collection1Alias)
.Left.JoinQueryOver(r=>r.Collection2,()=>collection2Alias)
.Right.JoinQueryOver(r=>r.Collection3)
.Full.JoinQueryOver(r=>r.People,()=>personAlias);

实际上,我用两种不同的方法解决了这个问题:

方法一:

Session.QueryOver<Foo>().Fetch(x => x.A).Fetch(x => x.A.B).Fetch(x => x.A.B.C)
Session.QueryOver().Fetch(x=>x.A).Fetch(x=>x.A.B).Fetch(x=>x.A.B.C)
方法二:

A a = null;
B b = null;
C c = null;

Session.QueryOver<Foo>()
    .JoinAlias(x => x.A, () => a)
    .JoinAlias(() => a.B, () => b)
    .JoinAlias(() => b.C, () => c)
A=null;
B=零;
C=零;
Session.QueryOver()
.JoinAlias(x=>x.A,()=>A)
.JoinAlias(()=>a.B,()=>B)
.JoinAlias(()=>b.C,()=>C)

这两种方法都有效(虽然我不确定其中一个是否生成“内部”连接,另一个是否生成“外部”连接)。

出于好奇,我将把他们给我的回复发布在:


方法2似乎只适用于一对一,它在集合上失败。我收回这一点,如果为集合指定联接类型,它确实有效,默认情况下它尝试内部联接。如果您指定了一个左外部联接,它就可以正常工作。Fetch()之后不需要FetchType(急切、懒惰、默认)吗?不。至少当我发布这个答案(使用NH3.0)时不是这样的,虽然这个答案是正确的,但在我自己的例子中,我特别想获取集合或列表的子对象。对于这种情况,@xanatos指出,您只需要访问集合/列表的第一个元素,就可以让C编译器满意:
query.Fetch(x=>x.SomeEnumerable).Fetch(x=>x.SomeEnumerable.first().SomeProperty)
当NHibernate实际检查这个lambda表达式时,它忽略对
.first()的调用
,只需查看属性链即可。意识到这一点对我来说意义重大。谢谢!这正是我需要看到的用法。
A a = null;
B b = null;
C c = null;

Session.QueryOver<Foo>()
    .JoinAlias(x => x.A, () => a)
    .JoinAlias(() => a.B, () => b)
    .JoinAlias(() => b.C, () => c)
query 
    .Fetch(p => p.B) 
    .Fetch(p => p.B.C) // if B is not a collection ... or 
    .Fetch(p => p.B[0].C) // if B is a collection ... or 
    .Fetch(p => p.B.First().C) // if B is an IEnumerable (using .First() extension method)