Nhibernate:急于加载两个子集合(一个是组件列表)

Nhibernate:急于加载两个子集合(一个是组件列表),nhibernate,Nhibernate,我有一个父类,它有两个子集合ChildCollectionA和ChildCollectionB。 ChildCollectionA映射为关联,并具有自己的ID: HasMany(parent => parent.ChildCollectionA) .KeyColumn("IDParent") .AsBag().Cascade.AllDeleteOrphan(); 并且ChildCollectionB映射有一个组件列表: HasMany(parent => parent.ChildC

我有一个父类,它有两个子集合ChildCollectionA和ChildCollectionB。 ChildCollectionA映射为关联,并具有自己的ID:

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();
我现在需要数据库中的所有父对象,因为我将必须执行一些同时需要ChildCollectionA和ChildCollectionB的操作

因此,我必须急切地加载它们,我首先使用fetch模式急切地加载ChildCollectionA:

var queryParents=session.CreateCriteria() .SetFetchMode(“ChildCollectionA”,FetchMode.Eager) .Add(Expression.Le(“ParentDate”,endDate))

它返回了492名家长(应该是481名),我执行的手术总价值为32847.46欧元(应该是30790.87欧元)。因此,我必须消除父级重复:

var queryParents = session.CreateCriteria<Parent>()
    .SetFetchMode("ChildCollectionA", FetchMode.Eager)
    .Add(Expression.Le("ParentDate",endDate))
    .SetResultTransformer(new DistinctRootEntityResultTransformer());
var queryParents=session.CreateCriteria()
.SetFetchMode(“ChildCollectionA”,FetchMode.Eager)
.Add(Expression.Le(“ParentDate”,endDate))
.SetResultTransformer(新DistincTrotentyResultTransformer());
我试着用同样的急切的方式来装载儿童收藏品B

var queryParents = session.CreateCriteria<Parent>()
    .SetFetchMode("ChildCollectionB", FetchMode.Eager)
    .Add(Expression.Le("ParentDate",endDate))
    .SetResultTransformer(new DistinctRootEntityResultTransformer());
var queryParents=session.CreateCriteria()
.SetFetchMode(“ChildCollectionB”,FetchMode.Eager)
.Add(Expression.Le(“ParentDate”,endDate))
.SetResultTransformer(新DistincTrotentyResultTransformer());
在这两种情况下,都返回了481个家长OK,值为30790.87欧元OK

但我需要同时加载这两个集合,我做到了:

var queryParents = session.CreateCriteria<Parent>()
    .SetFetchMode("ChildCollectionA", FetchMode.Eager)
    .SetFetchMode("ChildCollectionB", FetchMode.Eager)
    .Add(Expression.Le("ParentDate",endDate))
    .SetResultTransformer(new DistinctRootEntityResultTransformer());
var queryParents=session.CreateCriteria()
.SetFetchMode(“ChildCollectionA”,FetchMode.Eager)
.SetFetchMode(“ChildCollectionB”,FetchMode.Eager)
.Add(Expression.Le(“ParentDate”,endDate))
.SetResultTransformer(新DistincTrotentyResultTransformer());
它返回了481个OK,值为32602.57欧元(应为30790.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);
  }
var queryParents=session.CreateCriteria()
.SetFetchMode(“ChildCollectionA”,FetchMode.Eager)
.Add(Expression.Le(“ParentDate”,endDate))
.SetResultTransformer(新DistincTrotentyResultTransformer());
parents=queryParents.List();
foreach(父级中的父级p)
{
初始化(p.ChildCollectionB);
}
它返回481个OK,值为30790.87欧元OK

当我急切地加载两个集合时就会出现问题,如果我只急切地加载一个集合,然后强制将懒散的加载到另一个集合,它就会工作。我不知道ChildCollectionB作为组件列表而不是关联的映射是否与此有关

有什么线索吗


谢谢

我认为问题在于两个集合之间的笛卡尔积不是由DistincTrotentyTransformer处理的……因此在集合中的某个地方会有重复的数据

要急切地加载多个集合,需要进行多个查询

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();
var queryParents=session.CreateCriteria()
.SetFetchMode(“ChildCollectionA”,FetchMode.Eager)
.Add(Expression.Le(“ParentDate”,endDate))
.SetResultTransformer(新DistincTrotentyResultTransformer());
//在第二个查询中加载CollectionB…它由NH链接在一起
session.CreateCriteria()
.SetFetchMode(“ChildCollectionB”,FetchMode.Eager)
.Add(Expression.Le(“ParentDate”,endDate))
.List();
我通常做的是获取主实体以及所有必需的多对一关联。然后,我将急切地使用多标准将所需的集合提取到会话中。如果只有两个收藏,有时我确实喜欢上面的内容,并以独特的方式获取第一个收藏


有关更多信息,请参见

是否在nhibernate版本4特别是4.0.4中尝试过此功能?看来此解决方案在该版本中不起作用。