1

让我解释一下这个问题——希望我已经在标题中很好地定义了它,但我想确定一下。

我有一个 linq 查询,可以拉回一堆对象(比如 Foos)。每个 Foo 都包含一个对 User 的引用。每个用户都持有一个人的引用:

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,然后为所有用户和人员分别获得一个 SELECT。显然,我更喜欢带有几个连接的单个 SELECT。

我不一定要在我的映射配置中指定 Foos 总是渴望获取用户,或者用户总是渴望获取人,但我希望能够在这种情况下指定。

有没有办法做到这一点?

谢谢

大卫

4

3 回答 3

3

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

对于标准,你有SetFetchMode

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

对于Linq,你有Expand(2.x contrib) / Fetch(3.x)。

对于SQL,您有AddJoin.

于 2010-08-09T12:45:22.147 回答
0

Udi DahanRitesh Rao都为 NHibernate 提供了动态获取策略的示例实现,这应该给你一个很好的起点。

于 2010-08-09T11:42:45.167 回答
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+1N / 20 + 1,这非常好。

于 2010-08-09T14:18:50.737 回答