NHibernate, отдельные запросы (используя QueryOver) для заполнения сложного объекта - PullRequest
0 голосов
/ 05 декабря 2011

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

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

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

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();

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

Есть ли подход, который я могу использовать, который позволит мнепримените условие where к родительскому объекту и используйте результаты этого запроса для автоматического получения всех дочерних объектов.Обратите внимание, что дети могут пройти 3 уровня, например FruitBasket.Yoghurt.Flavour.Owners.

Любой совет приветствуется.

C # .NET 4, NHibernate 3.0

1 Ответ

1 голос
/ 05 декабря 2011
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();

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

...