【问题标题】:NHibernate Criteria with Distinct Parent Load All Children?具有不同父级的 NHibernate 标准加载所有子级?
【发布时间】:2014-11-07 16:54:23
【问题描述】:

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

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 中删除 EagerLoad。但我仍然没有得到我需要的东西。

【问题讨论】:

    标签: c# nhibernate fluent-nhibernate nhibernate-mapping fluent-nhibernate-mapping


    【解决方案1】:

    我建议使用 batch-size="" 设置。它最终会在
    1)我们发出的一个查询(query.List&lt;MessageQueue&gt;();),
    2) NHibernate 将使用一个(或几个)查询/ies 来为每个返回的MessageQueue 加载集合。

    19.1.5. Using batch fetching

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

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

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

    流畅的选择是(集合和类级别)

    .BatchSize(25)
    

    同时检查:

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

    【讨论】:

    • 默认设置为 20,所以不确定这将如何帮助:"* [NH-2593] - 对于 Microsoft SQL Server,默认批处理大小 (adonet.batch_size) 设置为 20在会话工厂配置中未明确定义的地方”。还有其他想法吗?
    • 这不相关。您正在插入两个不同的主题。仔细阅读:19.6. Batch updates您尝​​试过我的建议吗?这些将解决您的问题。域模型中的集合和延迟加载越多,1+N 问题就越少。
    • 好吧,我读得更仔细了。我之前尝试过您的建议(这就是为什么我寻找将其设置回默认值并发现 NH-2593 让我感到困惑的原因),但在我将它放在会话之前,这次我在 MessageQueue 的实体覆盖上尝试了它这似乎已经做到了。显然,直到现在我才意识到其中的区别。谢谢。
    • 很高兴看到这一点,我在每个班级和每个收藏中都有这个设置 - 非常高兴。享受很棒的 NHibernate :)
    猜你喜欢
    • 2012-03-13
    • 1970-01-01
    • 2013-07-25
    • 1970-01-01
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多