NHibernate渴望加载FetchMany仅用于子类

NHibernate eager load with FetchMany for subclass only

我有以下(简化的)层次结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Account
{
    AccountType Type;
    long Id;
    string Name;
}

public enum AccountType
{
    UsualAccount = 0,
    SpecialAccount = 1
}

class SpecialAccount : Account
{
    List<SpecialItem> SpecialItems;
}

class SpecialItem
{
    long Id;
    string Name;
}

为了帮助nhibernate检测子类特性,我在帐户映射中使用以下代码:

1
<discriminator column="Type" formula="Type"/>

而特性在映射中设置了lazy="false",但据我所知,它在LINQ查询期间被忽略。

现在,当我使用Linq和Call时

1
Session.Query<Account>().ToList();

我看到特殊项是在单独的查询中获取的。我很想把它们装上。

我可以用

1
Session.Query<Account>().FetchMany(a => a.SpecialItems).ToList();

但是有一个问题-专业是专业账户的属性。所以我需要费奇曼工作,只有当A是一个特殊的账户类。

我甚至尝试了一些像:

1
2
Session.Query<Account>().
    FetchMany(a => (a is SpecialAccount ? (a as SpecialAccount ).SpecialItems : null));

但NHibernate仍然在单独的查询中选择了专业。

如何在单个查询中使nhibernate为专用帐户选择专用项?

附加信息

我使用的是MS SQL Express 2012,nhibernate配置有以下几行:

1
2
3
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="adonet.batch_size">50</property>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>

nhibernate.dll版本3.2.0.4000

下面是nhibernate为一个id=2的现有特殊帐户生成的查询,它们出现在MS SQL事件探查器中(所选事件rpccompleted、exec-prepared-sql、sql:stmtcompleted):

1
2
3
4
select account0_.Id as Id5_, account0_.Type as Type5_, account0_.Name as Name5_, account0_.Type as clazz_ from tAccount account0_

exec sp_executesql N'SELECT specialite0_.AccountId as Id1_, specialite0_.Id as specialite1_1_, specialite0_.Id as specialite1_13_0_, specialite0_.Name as Name13_0_
FROM tSpecialItem specialite0_ WHERE specialite0_.Id=@p0',N'@p0 bigint',@p0=2

不能进行"条件提取"。您至少需要两个查询。

但是,您可以使用将来的LINQ查询对它们进行分组,因此这实际上是一次往返:

1
2
session.Query<SpecialAccount>().FetchMany(x => x.SpecialItems).ToFuture();
var accounts = session.Query<Account>().ToFuture();

两个查询都在枚举accounts时运行。我们不显式存储第一个查询的结果,但是SpecialAccounts与对应的SpecialItems集合一起加载到内存中,因此没有额外的db调用。