让我解释一下这个问题 - 希望我在标题中做得很好,但我想确定。
我有一个linq查询可以拉回一堆对象(比如说Foos)。每个Foo都拥有对用户的引用。每个用户都持有对人员的引用:
public class Foo
{
//properties omitted...
public User CreatedBy {get;}
}
public class User
{
//properties omitted...
public Person Person {get;set;}
}
正如对象结构所暗示的那样,在数据库中,Foo将多对一关联到User,而User将多对一关联到Person。
当我运行查询时,我为Foos获得一个SELECT,然后为所有Users和People获得一个SELECT。显然,我更喜欢单个SELECT和几个连接。
我不一定要在我的映射配置中指定Foos总是渴望获取用户,或者用户总是渴望获取Person,但我希望能够在此实例中指定。
有办法吗?
由于
大卫
答案 0 :(得分:3)
所有NHibernate查询方法都有指定eager提取的方法。
对于条件,您有SetFetchMode
。
对于 HQL ,您有[inner|left] join fetch
。
Linq 哟Expand
(2.x contrib)/ Fetch
(3.x)。
对于 SQL ,您有AddJoin
。
答案 1 :(得分:0)
Udi Dahan和Ritesh Rao都为NHibernate提供了动态提取策略的示例实现,这应该会给你一个很好的起点。
答案 2 :(得分:0)
除了Diegos不错的答案:你也可以使用批处理。这减少了N + 1问题而没有太大的痛苦:
在班级使用批量大小:
<class name="Person" batch-size="20">
...
</class>
在集合级别使用批量大小:
<map
name="SomeCollection"
batch-size="20">
...
</map>
当加载其中一个引用时,NHibernate使用如下查询一次加载20:
select ... from Person where user_fk in (23, 34, 6, 667, 6745, 234 ....)
因此它将N+1
变为N / 20 + 1
,这非常好。