NHibernate - 动态定义提取策略

时间:2010-08-09 10:44:26

标签: nhibernate select nhibernate-mapping eager-loading

让我解释一下这个问题 - 希望我在标题中做得很好,但我想确定。

我有一个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,但我希望能够在此实例中指定。

有办法吗?

由于

大卫

3 个答案:

答案 0 :(得分:3)

所有NHibernate查询方法都有指定eager提取的方法。

对于条件,您有SetFetchMode

对于 HQL ,您有[inner|left] join fetch

Linq Expand(2.x contrib)/ Fetch(3.x)。

对于 SQL ,您有AddJoin

答案 1 :(得分:0)

Udi DahanRitesh 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,这非常好。