у меня есть Родительский класс, который имеет два дочерних набора 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, являющегося списком компонента вместо ассоциации, некоторое отношение к этому...
Какие-либо подсказки?
Спасибо
Я считаю, что проблема в том, что декартово произведение между двумя коллекциями не обрабатывается 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. Если это только две коллекции, иногда я делаю это так, как указано выше, и получаю первую коллекцию с определенной рентабельностью.
Для получения дополнительной информации см. Агрегат активной загрузки со многими дочерними коллекциями