1

我一直在阅读并四处寻找黑白的答案。

让我们谈谈熟悉的 CustomerOrder问题。假设我加载了 100 个订单,每个订单都链接到一个且只有一个客户。

使用 Fluent NHibernate,我将使用References()我的链接OrderCustomer定义我的Not.LazyLoad()Fetch.Join()

现在我在假设,NHibernate 可以简单地加入这两个表,并且很容易水合实体。但是,在我的测试中,我总是看到 N+1 个查询(实际上可能只有唯一的 ID)。我可以分享我的代码和表格,但它可能会让你感到厌烦,所以

  • 是否有可能克服 Order->Customer 的 N+1 (一个->一个或者更确切地说是很多->一个)?或者我必须使用批处理或 Criteria API?
  • 如果可能的话,你能指点我一个 Fluent NHibernate 的例子吗?
4

4 回答 4

2

我不会像您正在做的实际查询那样看映射。默认情况下,我将所有映射保留为 LazyLoad 并根据需要覆盖。

我使用 Criteria API 进行查询,并根据需要使用 CreateAlias 连接其他表。强烈建议NHProf 查找和消除此类情况。

于 2011-03-18T13:29:12.597 回答
2

经常有人抱怨fetch="join" 不起作用。这是因为 HQL 不考虑它。您可以在 HQL 中声明它。

我使用 fetch="join" 希望提高性能,但在许多情况下停止使用它。问题是加入许多表可能会使 SQL Server 遇到最大列数限制。在某些情况下,您根本不需要数据,因此在映射文件中全局指定它并不是很有用。

所以我建议

  • 要么在 HQL 中使用显式连接获取,因为你知道数据是否实际被使用。
  • 或者对于任何其他情况,批处理是一个很好的解决方案,因为它们是透明的(您的代码不需要知道),利用延迟加载并同时减少 N+1 问题。
于 2011-03-18T14:03:22.990 回答
2

您好
有两种方法可以解决您的问题

a) 使用条件查询它看起来像这样

Session.CreateQuery(typeof(Order))
.Add(<Restrictions if any>)
.SetFetchMode("Customer",FetchMode.Eager)
.List<Order>();

b) 使用 HQL

Session.CreateQuery("select o from Order inner join fetch o.Customer where <conditionifany>").List<Order>();

希望这可以帮助..

于 2011-03-19T09:12:10.860 回答
0

您使用的是什么查询 API?

如果是 HQL,您可以使用join fetch急切检索关联。

对于 LINQ 和 QueryOver,使用.Fetch()

于 2011-03-19T21:05:07.427 回答