0

我有一个包含 OrderLines 集合的订单。每个 OrderLine 都有一个多对一的产品。对于所有订单,我有一个搜索窗口——默认情况下——在网格中显示所有订单。使用同一个窗口,我可以过滤包含给定产品的所有订单。我们的客户每天产生大约 700 个订单,订单平均有大约 35 行。

在搜索窗口中,我只显示存储在 Order 对象本身中的信息。但是,如果我过滤特定产品,它将初始化我与 OrderLine 集合的延迟加载关系以及与我的 OrderLine 中的产品的多对一关系。每个订单行被逐行查询,并且对于每一行,对产品表都有一个单独的查询。

所以平均每个订单我得到 35 个查询来初始化所有 OrderLine,加上 35 个查询来获取与该订单相关的产品。

一次加载所有订单行及其相关产品(如果不可能,每个订单的所有订单行)的最佳方式是什么?我知道我可以将我的多对一映射到 orderline 中的产品作为 fetch="join",但这仍然会给我留下 35 个单个查询来获取 orderlines+products。

仅供参考:目前我加载所有东西都是懒惰的。

有什么建议么?我可以在这里使用 Future 吗?

问候,特德

4

3 回答 3

3

你的batch-size设置是什么?

保持延迟加载不变,在两个集合映射上将其设置为 35,这应该将 1 + 35 + 35 个查询减少到 1 + 1 + 1。

<bag ... batch-size='35' ..> 

同样正如 Stefan 所指出的,您还需要 batch-size='35'在课程上进行设置。

于 2012-04-27T08:45:44.693 回答
0

在这种情况下,我不会检索订单实体本身。我将创建一个“视图”类,并通过使用 NHibernate 项目,我将返回那些仅包含您感兴趣的信息的“视图”类,并将其放在概览表单或页面中。搜索时,您可以执行一个新查询(只有一个),该查询检索您感兴趣的“OrderView”实例。

当您想要编辑订单或查看其详细信息时,我会加载实体。

于 2012-04-27T08:31:01.327 回答
0

您是否对加载的实体在内存中进行过滤操作?通常,您只想对那些包含相关产品订单行的订单执行查询。因此,您只需要根据查询结果填充您的窗口。无需遍历所有订单和所有订单行来填充仅包含一小部分数据的窗口。

在数据库服务器上进行过滤通常比从服务器获取所有数据并在 C# 中进行过滤要快得多。

您的描述对我来说并不完全清楚:鉴于您已经过滤了要显示的订单,您是否需要访问订单行和产品?
- 如果没有,您可以使用上述解决方案。
- 如果是,您可以对过滤后的订单查询进行连接提取,以直接将订单行与订单一起加载。连接获取不仅适用于 <many-to-one>,也适用于 <one-to-many>,因此您可以一次加载一些根实体及其子实体。如果根实体有很多很多列和多个子实体,则存在一些缺点,因为查询会为每个子实体冗余地检索根实体的数据。然而,在许多情况下(取决于整个系统配置)连接获取的好处远远超过了成本。

在您查询数据并且事先不清楚以下代码实际需要哪些数据的情况下,使用批量选择(使用 <batch-size>)可以帮助大大减少数据库往返次数。

于 2012-04-29T21:56:13.897 回答