Nhibernate, отдельные запросы (с использованием QueryOver) для заполнения сложного объекта
-
28-10-2019 - |
Вопрос
Мы используем базу данных, которая не поддерживает отступление запросов, поэтому в этом случае мы не можем использовать фьючерсы 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();
не мог проверить это хотя