使用NHibernate-Futures获取ManyToOne

时间:2012-12-01 16:45:42

标签: nhibernate nhibernate-futures

我有一个类图,类似于下面的图。

我正在使用此示例,因为它比解释我正在处理的域更简单。

public class Cheque {

   public FinanceAccount Account {get;set;}

   public Customer customer {get;set;}

   public Branch Branch {get;set;}
}

Cheque实体与这三个实体的其余部分有ManyToOne个关系。

现在的关系是非双向

如何编写有效的期货查询来获取Cheques的列表,这样我就无法获得N + 1来加载AccountCustomerBranch?< / p>

我尝试过使用左连接,但想知道是否可以使用简化的SQL

来完成

1 个答案:

答案 0 :(得分:3)

我们可以达到所需的结果(没有N + 1) - 但Futures将不是正确的NHibernate功能。我们可以使用它们,但是获取many-to-one实体的技巧在其他地方(见下文)。此处所述的期货:http://ayende.com/blog/3979/nhibernate-futures表示:

... Future()和FutureValue()本质上是一种将推迟查询执行的方式用于以后的日期,此时NHibernate将获得有关应用程序应该做什么的更多信息,并相应地优化它

因此我们可以将更多查询放入一个批处理中。查询可以是例如以下结果的查询集:

  • 总检查
  • 前20个检查预测
  • 上周取消的最高金额

因此,在这种情况下,我们可以将“不同”类型的查询放入Future

但是要在没有N + 1的情况下获取many-to-one个实体 - 我们可以使用标准Criteria API。因此,即使这些属性被映射为惰性,select也可以作为fetch:

<many-to-one name="Account" class="FinanceAccount" column="AccountId" 
       lazy="proxy" fetch="select"/>

此Criteria将只创建一个带左连接的选择:

var list = session.CreateCriteria<Cheque>()
  .SetFetchMode("Account", NHibernate.FetchMode.Join)
  .SetFetchMode("customer", NHibernate.FetchMode.Join)
  .SetFetchMode("Branch", NHibernate.FetchMode.Join)
  .Future<Cheque>()
  // or
  // .List<Cheque>() ... will be the same right now
  ;

这将导致只有一个SQL select语句,加入Check及其引用属性。