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

编程入门 行业动态 更新时间:2024-10-26 02:36:19
本文介绍了Nhibernate:渴望加载两个子集合(一个是组件列表)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个Parent类,该类具有两个子集合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的操作.

所以我不得不急于加载它们,我使用获取模式首先急于加载ChildCollectionA:

var queryParents = session.CreateCriteria() .SetFetchMode("ChildCollectionA",FetchMode.Eager) .Add(Expression.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€确定.

当我渴望加载两个集合时,如果我渴望仅加载一个,然后将延迟加载强制到另一个,则将发生问题.我不知道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急切地将所需的集合获取到会话中.如果有时只有两个集合,我有时会喜欢上面的方法,并以不同的根源获取第一个集合.

有关更多信息,请参见大量子集合的热负荷聚集

i have a Parent class that has two child collections ChildCollectionA and ChildCollectionB. ChildCollectionA is mapped as an association, and has its own ID:

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

and ChildCollectionB is mapped has a component list:

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

I need now all the Parents in the DataBase, because i will have to perform some operations that need both ChildCollectionA and ChildCollectionB.

So I had to eager load them, I used fetch mode to eager load ChildCollectionA first:

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

It returned 492 Parents (should be 481), the total value of the operation i performed was 32,847.46€ (should be 30,790.87€). So i has to eliminate Parent duplicates:

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

I tried the same eager loading with just the ChildCollectionB

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

In both cases returned 481 parents OK, and the value was 30,790.87€ OK.

But I needed to eager load both collections at the same time, I did this:

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

It returned 481 parents OK, and the value was 32,602.57€ (should be 30,790.87€).

Now the number of parents returned is correct, but there are duplicates somewhere else, the values depend on the collections and not the parent, so the duplicates must be somewhere in the ChildCollections.

Right now i'm using an ugly solution:

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

It returned 481 parents OK, and the value was 30,790.87€ OK.

The problem happens when i eager load both collections, if i eager load just one, and then force the lazyload to the other, its works. I don't know if the mapping of ChildCollectionB being a component list instead of an association has something to do with this...

Any clues?

Thanks

解决方案

I believe the problem is the Cartesian product between the two collections is not handled by the DistinctRootEntityTransformer...so you'll have duplicated data in the collections somewhere.

To load multiple collections eagerly it's going to take multiple queries.

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

What I normally do is fetch the main entity along with all the required many-to-one associations. Then I'll eagerly fetch required collections into the session with a MultiCriteria. If it's only two collections sometimes I do like above and fetch the first collection with distinctrootentity.

For more info see Eager loading aggregate with many child collections

更多推荐

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

本文发布于:2023-11-29 00:14:37,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1644523.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:个子   组件   加载   列表   Nhibernate

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!