NHibernate ленивая загрузка вложенных коллекций с фьючерсами, чтобы избежать N +1 проблема

У меня есть объектная модель, которая выглядит так (псевдокод):

class Product {
    public ISet<Product> Recommendations {get; set;}
    public ISet<Product> Recommenders {get; set;}
    public ISet<Image> Images {get; set; }
}

Когда я загружаю данный продукт и хочу отобразить изображения его рекомендаций, я сталкиваюсь с проблемой N + 1. (Рекомендации загружаются лениво, затем цикл вызывает свойство .Images каждого из них.)

Product -> Recommendations -> Images

Я хочу с нетерпением загрузить именно эту часть графика, но не могу понять, как это сделать. . Я охотно загружаю рекомендации, но не их изображения. Это то, что я пробовал, но, похоже, это не сработало:

//get the IDs of the products that will be in the recommendations collection
var recommendedIDs = QueryOver.Of<Product>()
    .Inner.JoinQueryOver<Product>(p => p.Recommenders)
    .Where(r => r.Id == ID /*product we are currently loading*/)
    .Select(p => p.Id);

//products that are in the recommendations collection should load their 
//images eagerly
CurrentSession.QueryOver<Product>()
    .Fetch(p => p.Images).Eager
    .Where(Subqueries.WhereProperty<Product>(p => p.Id).In(recommendedIDs))
    .Future<Product>();

//load the current product
return CurrentSession.QueryOver<Product>()
    .Where(p => p.Id == ID);

Как лучше всего добиться этого с помощью QueryOver? Я не хочу постоянно загружать изображения постоянно, только в этом конкретном сценарии.


РЕДАКТИРОВАТЬ : я изменил свой подход, и, хотя это не совсем то, что я имел в виду, он избегает N + 1 проблема. Сейчас я использую два запроса: один для продукта, а другой - для изображений его рекомендаций. Запрос продукта прямолинейный; вот запрос изображения:

//get the recommended product IDs; these will be used in
//a subquery for the images
var recommendedIDs = QueryOver.Of<Product>()
    .Inner.JoinQueryOver<Product>(p => p.Recommenders)
    .Where(r => r.Id == RecommendingProductID)
    .Select(p => p.Id);

//get the logo images for the recommended products and
//create a flattened object for the data
var recommendations = CurrentSession.QueryOver<Image>()
    .Fetch(i => i.Product).Eager
    /* filter the images down to only logos */
    .Where(i => i.Kind == ImageKind.Logo)
    .JoinQueryOver(i => i.Product)
    /* filter the products down to only recommendations */
    .Where(Subqueries.WhereProperty<Product>(p => p.Id).In(recommendedIDs))
    .List().Select(i => new ProductRecommendation {
        Description = i.Product.Description,
        ID = i.Product.Id,
        Name = i.Product.Name,
        ThumbnailPath = i.ThumbnailFile
    }).ToList();

return recommendations;
14
задан Nicholas Cloud 7 March 2011 в 03:39
поделиться