防止Fluent NHibernate选择n + 1

时间:2009-02-24 10:14:19

标签: nhibernate select fluent-nhibernate

我有一个相当深的对象图(5-6个节点),当我遍历它的部分时,NHProf告诉我我有一个“选择N + 1”问题(我这样做)。

我知道的两个解决方案是

  1. 渴望加载儿童
  2. 分解我的对象图(并急切加载)
  3. 我真的不想做其中任何一个(虽然我可能会在以后看到图表分开,因为我预测它会增长)

    现在......

    是否有可能告诉NHibernate(使用FluentNHibernate)每当我尝试访问子节点时,一次性加载它们,而不是select-n + 1-ing,因为我迭代它们?

    我也得到了“无限结果集”,这可能是同样的问题(或者更确切地说,如果可能的话,将由上述解决方案解决)。

    每个子集合(整个图表)将只有大约20个成员,但20 ^ 5很多,所以我不想在我获得root时急切加载所有内容,而只是让所有的孩子每当我靠近它时收集。

    编辑:一个事后的想法....如果我想在渲染孩子时引入分页怎么办?我是否必须在这里打破我的对象图,或者我可以用一些偷偷摸摸来解决所有这些问题?

2 个答案:

答案 0 :(得分:9)

在我看来,您希望采用使用域模型的方法,而不是创建特定的nhibernate查询来处理这种情况。鉴于此,我建议您查看可以应用于集合的batch-size属性。 Fluent NHibernate流畅的界面尚不支持此属性,但作为解决方法,您可以使用:

HasMany(x => x.Children).AsSet().SetAttribute("batch-size", "20")

鉴于一般缺乏有关您的确切方案的信息,我无法确定批量大小是否是理想的解决方案,但我当然建议您试一试。如果你还没有,我建议你阅读这些:

http://www.nhforge.org/wikis/howtonh/lazy-loading-eager-loading.aspx

http://nhibernate.info/doc/nhibernate-reference/performance.html

NHibernate性能文档将解释批量大小的工作原理。

编辑:我不知道有任何方法可以从您的域模型中进行分页。我建议您在需要分页的情况下编写NH查询。

答案 1 :(得分:0)

  

编辑:事后的想法....如果我   想要在我想要时引入分页   给孩子们?我必须打破   我的对象图在这里,还是有一些   偷偷摸摸我可以用来解决所有问题   这些问题?

好吧,如果您只加载孩子,那么您可以将它们分页:)。但是如果你想要类似:LoadParent和PageChildren,那么我认为你不能这样做。