【问题标题】:Fetching ManyToOne using NHibernate-Futures使用 NHibernate-Futures 获取多对一
【发布时间】:2012-12-01 16:45:41
【问题描述】:

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

我使用这个例子是因为它比解释我正在研究的领域更简单。

public class Cheque {

   public FinanceAccount Account {get;set;}

   public Customer customer {get;set;}

   public Branch Branch {get;set;}
}

Cheque 实体与其余三个实体具有 ManyToOne 关系。

目前的关系不是双向的

如何编写有效的期货查询来获取Cheques 的列表,这样我在加载AccountCustomerBranch 时就不会得到N+1?

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

【问题讨论】:

    标签: nhibernate nhibernate-futures


    【解决方案1】:

    我们可以实现所需的结果(没有 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。所以即使这些属性被映射为懒惰的选择作为获取:

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

    此条件将仅创建一个带有左连接的选择:

    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 选择语句,加入 Check 及其引用属性。

    【讨论】:

      猜你喜欢
      • 2013-10-11
      • 1970-01-01
      • 2017-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多