具有不同父代负载的NHibernate标准所有子代

本文关键字:NHibernate 标准 负载 | 更新日期: 2023-09-27 18:29:40

我有一个父子关系,我只想返回一个父级并加载所有子级。我之所以使用条件,是因为它是一个动态查询。

var messageQueueId = this.GetPropertyName<MessageQueue>(x => x.Id);
var query = _sessionManager.Session.CreateCriteria<MessageQueue>(QUEUE_ALIAS);
query.SetFirstResult(_pageOffset);
query.SetMaxResults(_pageSize);
query.Add(Restrictions.In(messageQueueId, _messageQueueIds));
query.List<MessageQueue>();

这将返回父级(MessageQueue),但不返回其子级(SearchMatches)。

当我尝试这样做时:

var query = _sessionManager.Session
    .CreateCriteria<MessageQueue>(QUEUE_ALIAS)
    .CreateAlias(this.GetPropertyName<MessageQueue>(x => x.SearchMatches)
                , MATCH_ALIAS, JoinType.LeftOuterJoin);

然后我把孩子们装上,但我也收到了重复的父母。我理解为什么会发生这种事。然而,我不明白如何让第一个场景自动加载SearchMatches?

以下是我的实体:

public class MessageQueue : EntityBase
{
    ...
    public virtual IList<SearchMatch> SearchMatches { get; set; }
    ...
}
public class SearchMatch : EntityBase
{
    ...
    public virtual MessageQueue MessageQueue { get; set; }
    ...
}

Fluent NHibernate设置为DefaultCascade.All()。我没有这些对象的其他替代。

我已尝试在MessageQueue覆盖之外使用Inverse()Not.LazyLoad()。还尝试过从CreateAlias中EagleLoad。但我仍然没有得到我需要的东西。

具有不同父代负载的NHibernate标准所有子代

我建议使用batch-size=""设置。它将在
中结束1) 我们发出的一个查询(query.List<MessageQueue>();),
2) NHibernate将使用一个(或几个)查询来为每个返回的MessageQueue加载集合。

19.1.5.使用批量取数

NHibernate可以有效地利用批量获取,也就是说,如果访问一个代理(或集合),NHibernat可以加载几个未初始化的代理。批量获取是懒惰选择获取策略的优化。有两种方法可以调整批量获取:在类和集合级别。

类/实体的批量获取更容易理解。假设您在运行时遇到以下情况:在一个ISession中加载了25个Cat实例,每个Cat都有一个对其所有者Person的引用。Person类使用代理进行映射,lazy="true"。如果您现在遍历所有的猫并调用cat。在每个所有者上,NHibernate将默认执行25条SELECT语句,以检索代理的所有者。您可以通过在Person:的映射中指定批量大小来调整此行为

<class name="Person" batch-size="10">...</class>

流利的替代方案是(集合级和类级)

.BatchSize(25)

同时检查:

  • 在使用Oracle时,如何使用Fluent NHibernate实现批量获取
  • 如何在NHibernate中不重复地加载关联
  • NHibernate QueryOver,Fetch生成多个sql查询和数据库命中

注意:最后,作为批次大小传递的数字,例如25,似乎被用作其一半-12。因此,如果您在25的大小上进行分页,请尝试使用SetBatchSize(50)