Как загрузить дочернюю коллекцию после загрузки родителя с помощью nhibernate? - PullRequest
0 голосов
/ 23 февраля 2012

У меня есть эта модель

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

ProductChannelAffectation
- Channel Channel
- Product Product
- double Price

Итак, я хочу получить 10 первых товаров, которые соответствуют некоторым условиям и их влиянию, в 2 запросах (без проблем N + 1) и, если возможно, в 1 поездке вБД.

Итак, я прочитал этот ответ

https://stackoverflow.com/a/7035649/277067 ИЛИ этот https://stackoverflow.com/a/5285739/277067

Но здесь есть 2 проблемы:

  • Условие дублируется "Где (x => x.Id == ID)" в двух запросах, это нормально, когда это простое условие, но что, если это сложные условия (включая другие таблицы, текстовый поиск)...)

  • Условие "Верх" отсутствует.

При отложенной загрузке возникает проблема 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 ]

1 голос
/ 23 февраля 2012

Вы пытались установить размер пакета

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

Это остановит вашу проблему n + 1 и позволит вам сохранить ленивую загрузку.В основном, установив размер пакета в 50, вы уменьшите количество запросов к базе данных в 50 раз. Без этого, если у вас было 99 строк, вы бы отправили 99 запросов к базе данных с набором размера пакета, который вы бы выполнили 2.

0 голосов
/ 23 февраля 2012
// 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...