使用nhibernate(和queryover)急切地获取多个嵌套关联

时间:2011-05-24 17:46:01

标签: nhibernate collections associations fetch queryover

我有一个拥有多个嵌套关联的数据库。基本上,结构如下:

Order -> OrderItem -> OrderItemPlaylist -> OrderPlaylistItem -> Track -> Artist

我需要根据特定日期销售的所有订单生成报告,该报告需要遍历所有提到的关联,以便生成所需的信息。

尝试将所有表连接在一起将是一种过度杀伤,因为它将导致具有许多冗余数据的极大笛卡尔连接,考虑到它将连接6个表。代码如下:

q.Left.JoinQueryOver<OrderItem>(order => order.OrderItems)
     .Left.JoinQueryOver<OrderItemPlaylist>(orderItem => orderItem.Playlist)
     .Left.JoinQueryOver<OrderItemPlaylistItem>(orderItemPlaylist => orderItemPlaylist.PlaylistItems)
     .Left.JoinQueryOver<Track>(orderItemPlaylistItem => orderItemPlaylistItem.Track)
     .Left.JoinQueryOver<Artist>(track => track.Artist)

上述工作,但即使是几个订单,每个订单都有几个订单项,每个播放列表都包含多个曲目,结果会爆炸成千条记录,每增加一个订单就会成倍增长。

知道什么是最好和最有效的方法?我目前尝试启用批量加载,这大大减少了数据库查询的数量,但在我看来似乎并不像一个好的方法,但更像是一个“简单的解决方法”。

在给定大量数据的情况下,不需要在一个SQL查询中加载所有数据。我想,每个关联的一个SQL查询都是完美的。理想情况下,首先获得所有订单,然后获取订单的所有订单商品并将其加载到关联的集合中,然后加载每个订单商品的播放列表,依此类推。

此外,这不一定是在QueryOver中,因为我可以访问.RootCriteria并使用Criteria API。

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:0)

如果您更喜欢一个SQL查询,您希望生成哪种SQL语法?如果您要进行一次SQL查询,我想您无法避免长JOIN个序列。

我想我要做的是使用多个查询逐级获取实体。

答案 1 :(得分:0)

您可能应该首先在SQL中尽可能地定义查询,并查看执行计划以找到最佳方法(以及您的索引是否足够)。

此时你知道你正在拍摄什么,然后在HQL或QueryOver甚至LINQ中尝试编写查询并使用NHibernate中的SQL编写器或优秀的NHProfiler {{来检查结果相当容易。 3}}

你最终可能会遇到几个问题。通过使用Criteria或QueryOver中的“Future”命令,通过尽可能多地(不依赖于彼此)批处理来加速它们。您可以在此处详细了解:http://www.nhprof.com

答案 2 :(得分:0)