Nhibernate, отдельные запросы (с использованием QueryOver) для заполнения сложного объекта

StackOverflow https://stackoverflow.com/questions/8381196

Вопрос

Мы используем базу данных, которая не поддерживает отступление запросов, поэтому в этом случае мы не можем использовать фьючерсы Nhibernate. Мы знаем, что мы все еще можем заполнить наш сложный объектный график, используя несколько кверов (чтобы избежать декартовых продуктов), но нуждаемся в совете, если я могу рефакторировать подход.

Пожалуйста, обратите внимание> Единственный разработчик здесь, так что обращайтесь за советом.

Вот какой -то пример кода, который иллюстрирует текущий подход;

var fruitBasketAlias = new Store.FruitBasket(); 
var yoghurtAlias = new Store.Yoghurt();
var flavourAlias = new Store.Flavour();
var ownersAlias = new Store.Owner();

var FruitBaskets = session.QueryOver(() => fruitBasketAlias)
    .Where(() => fruitBasketAlias.Owner.ID == OwnerID
                    && fruitBasketAlias.ExpiryDate <= dateTO
                    && fruitBasketAlias.ExpiryDate >= dateFROM)
    .Fetch(x => x.BasketLiner).Eager
    .List();

session.QueryOver(() => fruitBasketAlias)
    .Select(x => x.Yoghurts)
    .Where(() => fruitBasketAlias.Owner.ID == OwnerID
                    && fruitBasketAlias.ExpiryDate <= dateTO
                    && fruitBasketAlias.ExpiryDate >= dateFROM)
    .JoinAlias(() => fruitBasketAlias.Yoghurts, () => yoghurtAlias, JoinType.LeftOuterJoin)
    .JoinAlias(() => yoghurtAlias.Flavour, () => flavourAlias, JoinType.InnerJoin)
    .List();

session.QueryOver(() => fruitBasketAlias)
    .Where(() => fruitBasketAlias.Owner.ID == OwnerID
                    && fruitBasketAlias.ExpiryDate <= dateTO
                    && fruitBasketAlias.ExpiryDate >= dateFROM)
    .JoinAlias(() => fruitBasketAlias.Yoghurt, () => yoghurtAlias, JoinType.LeftOuterJoin)
    .JoinAlias(() => yoghurtAlias.Flavour, () => flavourAlias, JoinType.InnerJoin)
    .JoinAlias(() => flavourAlias.Owners, () => ownersAlias, JoinType.LeftOuterJoin)
    .List();

Из приведенного выше кода вы можете видеть, что я использую три отдельных запроса для заполнения списка фруктов. Этот подход работает, но я подозреваю, что есть лучший способ присоединиться к всем детям в родительский объект без необходимости запрашивать от корневого объекта каждый раз.

Существует ли подход, который я могу использовать, который позволит мне применить условие, где к родительскому объекту условие и использовать результаты этого запроса для автоматического получения всех объектов детей. Обратите внимание, что дети могут пройти 3 уровня глубиной, то есть FruitBasket.yoghurt.flavour.owners.

Любой совет ценится.

C# .net 4, Nhibernate 3.0

Это было полезно?

Решение

var FruitBaskets = session.QueryOver<FuitBasket>()
    .Where(b => b.Owner.ID == OwnerID
                    && b.ExpiryDate <= dateTO
                    && b.ExpiryDate >= dateFROM)
    .Fetch(x => x.BasketLiner).Eager
    .JoinAlias(b => b.Yoghurts, () => yoghurtAlias, JoinType.LeftOuterJoin)
    .List();

var yoghurts = session.QueryOver<Store.Yoghurt>()
    .WhereRestrictionOn(y => y.Id).In(FruitBaskets.SelectMany(b => b.Yoghurts).Select(y = > y.Id).Distinct())
    .JoinAlias(y => y.Flavour, () => flavourAlias, JoinType.InnerJoin)
    .List();

session.QueryOver<Store.Flavor>()
    .WhereRestrictionOn(f => f.Id).In(yoghurts.SelectMany(y => y.Flavors).Select(b = > f.Id).Distinct())
    .JoinAlias(f => f.Owners, () => ownersAlias, JoinType.LeftOuterJoin)
    .List();

не мог проверить это хотя

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top