Nhibernate: нетерпеливая загрузка двух дочерних наборов (один являющийся списком компонента)

у меня есть Родительский класс, который имеет два дочерних набора ChildCollectionA и ChildCollectionB. ChildCollectionA отображается как ассоциация и имеет свой собственный идентификатор:

HasMany(parent => parent.ChildCollectionA)
.KeyColumn("IDParent")
.AsBag().Cascade.AllDeleteOrphan();

и ChildCollectionB отображается, имеет список компонента:

HasMany(parent => parent.ChildCollectionB)
    .Table("ChildCollectionBTable")
    .KeyColumn("IDParent")
    .Component(m=>
                {
                    m.References(childB => childB.Task, "IDTask").Not.LazyLoad().Not.Nullable();
                    m.Map(childB  => childB.Date, "Date").Not.Nullable();

                } 
        )
    .AsBag().Cascade.AllDeleteOrphan();

Мне нужны теперь все Родители в DataBase, потому что я должен буду выполнить некоторые операции, для которых нужны и ChildCollectionA и в ChildCollectionB.

Таким образом, я имел к нетерпеливому, загружают их, я привык режим выборки для нетерпеливой загрузки ChildCollectionA сначала:

  var queryParents = сессия. CreateCriteria ()    .SetFetchMode ("ChildCollectionA", FetchMode. Нетерпеливый)    .Add (Выражение. Le ("ParentDate", endDate));

Это возвратилось, 492 Родителя (должен быть 481), итоговое значение операции, которую я выполнил, составляло 32 847,46€ (должны быть 30 790,87€). Таким образом, я должен устранить Родительские дубликаты:

var queryParents = session.CreateCriteria<Parent>()
    .SetFetchMode("ChildCollectionA", FetchMode.Eager)
    .Add(Expression.Le("ParentDate",endDate))
    .SetResultTransformer(new DistinctRootEntityResultTransformer());

Я попробовал ту же нетерпеливую загрузку просто ChildCollectionB

var queryParents = session.CreateCriteria<Parent>()
    .SetFetchMode("ChildCollectionB", FetchMode.Eager)
    .Add(Expression.Le("ParentDate",endDate))
    .SetResultTransformer(new DistinctRootEntityResultTransformer());

В обоих случаях возвращенный 481 родитель хорошо и значение были 30 790,87€ хорошо.

Но мне были нужны к нетерпеливой загрузке оба набора одновременно, я сделал это:

var queryParents = session.CreateCriteria<Parent>()
    .SetFetchMode("ChildCollectionA", FetchMode.Eager)
    .SetFetchMode("ChildCollectionB", FetchMode.Eager)
    .Add(Expression.Le("ParentDate",endDate))
    .SetResultTransformer(new DistinctRootEntityResultTransformer());

Это возвратило 481 родителя хорошо, и значение составляло 32 602,57€ (должны быть 30 790,87€).

Теперь количество возвращенных родителей корректно, но существуют дубликаты где-то в другом месте, значения зависят от наборов а не родителя, таким образом, дубликаты должны быть где-нибудь в ChildCollections.

Прямо сейчас я использую ужасное решение:

var queryParents = session.CreateCriteria<Parent>()
    .SetFetchMode("ChildCollectionA", FetchMode.Eager)
    .Add(Expression.Le("ParentDate",endDate))
    .SetResultTransformer(new DistinctRootEntityResultTransformer());

parents= queryParents.List<Parent>();

  foreach (Parent p in parents)
  {
      NHibernateUtil.Initialize(p.ChildCollectionB);
  }

Это возвратило 481 родителя хорошо, и значение составляло 30 790,87€ хорошо.

Проблема происходит, когда я нетерпеливая загрузка оба набора, если я нетерпеливая загрузка всего один, и затем вызываю lazyload к другому, его работам. Я не знаю, имеет ли отображение ChildCollectionB, являющегося списком компонента вместо ассоциации, некоторое отношение к этому...

Какие-либо подсказки?

Спасибо

8
задан Răzvan Flavius Panda 13 March 2013 в 16:49
поделиться

1 ответ

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

Чтобы быстро загрузить несколько коллекций, потребуется несколько запросов.

var queryParents = session.CreateCriteria<Parent>()
    .SetFetchMode("ChildCollectionA", FetchMode.Eager)
    .Add(Expression.Le("ParentDate",endDate))
    .SetResultTransformer(new DistinctRootEntityResultTransformer());

//load CollectionB in second query...it's linked together by NH
session.CreateCriteria<Parent>()
    .SetFetchMode("ChildCollectionB", FetchMode.Eager)
    .Add(Expression.Le("ParentDate",endDate))
    .List();

Обычно я выбираю основную сущность вместе со всеми необходимыми однозначными ассоциациями. Затем я с нетерпением загружу необходимые коллекции в сеанс с помощью MultiCriteria. Если это только две коллекции, иногда я делаю это так, как указано выше, и получаю первую коллекцию с определенной рентабельностью.

Для получения дополнительной информации см. Агрегат активной загрузки со многими дочерними коллекциями

4
ответ дан 6 December 2019 в 00:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: