如何在使用nhibernate加载父代后加载子集合?

时间:2012-02-23 12:54:37

标签: c# nhibernate

我有这个模型

Product
- int Id
- string Name
- List<ProductChannelAffectation> Affectations

ProductChannelAffectation
- Channel Channel
- Product Product
- double Price

所以我想得到10个第一个与某些条件匹配的产品及其在2个查询中的表示(没有N + 1问题),如果可能的话,可以在1个DB中获取。

所以我读了这个答案

https://stackoverflow.com/a/7035649/277067 或者这一个 https://stackoverflow.com/a/5285739/277067

但这里有2个问题:

  • 条件重复&#34;其中(x =&gt; x.Id == ID)&#34;在2个查询中,如果条件简单,那就没问题,但如果条件复杂(包括其他表格,文本搜索......)

  • 没有&#34; Top&#34;条件。

延迟加载导致N + 1问题。

我试过这个

var products = _nhSession.QueryOver<Product>()
    .Where(...)
    .Take(10)
    .List()
    .ToList();
var idsproduct = products.Select(p => p.ID);
var affectation = _nhSession.QueryOver<ProductChannel>()
    .Where(c => c.Product.ID.IsIn(idsproduct))
    .ToList();

但在执行第二个查询之前,仍有N + 1(用于获取影响)。

以下是我的协会宣布的方式

  <bag name="Affectations" access="property" table="Product" lazy="false">
      <key column="n_Product" />
      <one-to-many class="CTV.ProductChannel, CTV" />
    </bag>

我正在使用activerecord进行声明。

2 个答案:

答案 0 :(得分:1)

您是否尝试过设置批量大小

 <bag name="Affectations" ... batch-size='50'>

这将停止你的n + 1问题并允许你保持延迟加载。基本上将批量大小设置为50将减少发送到数据库的查询量50倍。如果你有99行,你将发出99个查询到批量大小设置的数据库,你将发出2。 / p>

答案 1 :(得分:0)

// subquery for the ids
var idsproduct = QueryOver.Of<Product>()
    .Where(...)
    .Take(10);
var affectation = _nhSession.QueryOver<Product>()
    .WithSubquery.Where(p => p.ID).In(idsproduct))
    .Fetch(p => p.Affectations).Eager
    .ToList();