【问题标题】:How to eager load objects in a list/collection?如何在列表/集合中急切加载对象?
【发布时间】:2015-09-22 15:49:44
【问题描述】:

我有以下疑问:

ObjectB objectBAlias = null;
ObjectC objectCAlias = null;
var query = session.QueryOver<ObjectA>();
var results = query
    .JoinAlias(x => x.listOfBs, () => objectBAlias)
    .JoinAlias(x => objectBAlias.ObjectC, () => objectCAlias)
    .TransformUsing(new DistinctRootEntityResultTransformer())
    .List<ObjectA>();

class ObjectA
{
    IList<ObjectB> listOfBs;
}

class ObjectB
{
    ObjectA a;
    ObjectC c;
}

class ObjectC
{
    int x;        
}

ObjectA 与 ObjectC 具有many-to-many 关系,其中 ObjectB 是连接表。 ObjectA 有一个 ObjectB 的列表,而 ObjectB 有一个 ObjectC 的比例。我正在尝试加载 ObjectC,但没有成功。

我让所有的 ObjectC 急切加载的唯一方法是这样做:

foreach (ObjectA a in results)
{
    foreach (var b in a.listOfBs)
    {
        NHibernateUtil.Initialize(b.c);
    }
}

但这似乎不能很好地扩展。

【问题讨论】:

    标签: nhibernate nhibernate-mapping queryover


    【解决方案1】:

    我建议 - 不要尝试 (渴望加载多对多)。相反 - 使用内置功能:

    19.1.5. Using batch fetching

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

    要了解更多详情,请查看以下内容:

    获取集合是一项困难的操作。它有许多副作用(正如您所意识到的,当获取更多集合时)。但即使获取一个集合,我们也会加载许多重复的行。

    【讨论】:

    • 那么在 ObjectB 上放置一个batch-size 是否允许我在会话之外调用result[0].listOfBs[0].c.x(又名热切加载)?还是我看错了?
    • 我放在两边的那个设置! 1) 在&lt;class .. batch-size="50" - 支持many-to-one 的有效加载和2) 在&lt;bag ... batch-size="50"... 完全支持一对多(和多对多)... 现在有帮助吗?
    • 看来它成功了,谢谢!你能解释一下它在做什么吗?
    • 是的!这里的重点是我们使用了一些“优化”设置。它旨在解决1 + N问题。它创建了一些更智能的选择(带有相当大的IN 语句),以尽可能在少数个数据库往返中加载许多个实体.我们可以轻松地查询根实体,并获取所有接触到的关系 - 1) 懒惰地和 2) 批量 (在此处查看其他详细信息 stackoverflow.com/a/32456516/1679310).. 希望对您有所帮助。先生,享受强大的 NHibernate ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 2011-12-03
    • 2015-05-08
    • 1970-01-01
    • 2013-07-28
    相关资源
    最近更新 更多