让我解释一下这个问题-希望我在标题中已经很好地定义了它,但我想确定一下。
我有一个linq查询,它拉回一堆对象(比如Foos)。每个Foo都包含一个对用户的引用。每个用户都有一个对一个人的引用:
public class Foo
{
//properties omitted...
public User CreatedBy {get;}
}
public class User
{
//properties omitted...
public Person Person {get;set;}
}
正如对象结构所暗示的那样,在数据库中,Foo将多对一关联到用户,而用户将多对一关联到人。
当我运行查询时,我对Foos执行了一次SELECT,然后对所有用户和人员执行了一次SELECT each。显然,我更喜欢有几个连接的单个SELECT。
我不一定要在我的映射配置中指定Foos总是急切地获取用户,或者用户总是急切地获取人员,但我希望能够在本例中指定这一点。
有没有办法做到这一点?
谢谢
大卫
发布于 2010-08-09 20:45:22
所有的NHibernate查询方法都有指定立即获取的方法。
对于Criteria,您可以使用SetFetchMode
。
对于HQL,您可以使用[inner|left] join fetch
。
对于,Linq yo有Expand
(2.x contrib) / Fetch
(3.x)。
对于SQL,您可以使用AddJoin
。
发布于 2010-08-09 19:42:45
Udi Dahan和Ritesh Rao都为NHibernate提供了动态获取策略的示例实现,这应该是一个很好的起点。
发布于 2010-08-09 22:18:51
另外,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
,这是非常好的。
https://stackoverflow.com/questions/3439237
复制相似问题