【问题标题】:How to fetch objects multiple levels deep and wide with NHibernate?如何使用 NHibernate 获取多个层次的对象?
【发布时间】:2011-09-08 19:34:27
【问题描述】:

我有一个案例,我需要从数据库中加载大约 10 000 个对象。数据模型是这样的:

public class SimulationObject
{
    public Container Container {get;set;}
    public IList<ResultItem> Results {get;set;}
    public IList<PreviewData> PreviewData {get;set;}
    ...
}

public class ResultItem
{
    public IList<SomeDataItem> Items {get;set;}
    ...
}

public class PreviewData
{
    public IList<SomeDataItem> Items {get;set;}
    ...
}

这意味着我想根据一些查询从数据库中查询一个 SimulationObjects 列表,以及它的所有属性(引用)和子项。

收藏数量如下:

  1. SimulationObject - ca 6000 - 1200,取决于“where”中的参数
  2. SimulationObject.Results - 大约 5 到 40 个项目
  3. SimulationObject.Results.Items - 大约 0 到 2 个项目
  4. SimulationObject.PreviewData - 大约 0 到 2 个项目
  5. SimulationObject.PreviewData.Items - 大约 1 到 3 个项目

通常,我会这样做:

var query = from sim in session.Query<SimulationObject>()
        where sim.Container.Id == containerId && ...
            select sim;

query = query.FetchMany(c => c.Results).ThenFetch(o => o.Items)...

但是,我还需要获取“PreviewData”项目,因为这会在我的查询中创建一个笛卡尔积(意味着 PreviewDataAndSubItemsCount x ResultsAndSubItemsCount 返回的行数),这是非常无效的。另外,由于我需要加载很多 SumulationObjects(如前所述大约 10000 个),我不能进行延迟加载(10000 个查询......而且还有其他困难,所以这甚至不是考虑的替代方案)。

那么有什么选择呢?您将使用什么策略将复杂对象图加载到内存中?

谢谢。

【问题讨论】:

  • 10,000 SimulationObjects 是一个确定的数字,还是未来可能会增长?平均而言,每个SimulationObject 有多少个ResultItems?每个SimulationObject 有多少个PreviewData?每个PreviewDataResultItem 有多少SomeDataItems?您是否还需要获取SomeDataItems,或者这些孙子可以延迟加载?
  • SimulationObject 中,PreviewDataResultItem 是否分享他们的SomeDataItems?换句话说,给定SomeDataItem x,这句话是真的吗:x.ResultItem.SimulationObject == x.PreviewData.SimulationObject?如果是这样,那么您有一个菱形关系,这会影响我们需要对这些孙对象进行多少获取。
  • 不,他们不共享关系。实际上,PreviewData 项和 ResultItem 项保存在 db 的不同表中。 SomeDataItem 类是伪代码。哦,我在帖子中添加了数量。

标签: c# nhibernate nhibernate-mapping linq-to-nhibernate nhibernate-criteria


【解决方案1】:

Ayende 在这里解释了一种方法(HQL):
http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate

我还看到了一篇 StackOverflow 文章,它使用 QueryOver 来做到这一点:
NHibernate Eager Loading with Queryover API on a complex object graph

不过,我很想从 hte 社区的其他人那里获得更多的意见。我认为这是 NH 可以改进的一个领域。

【讨论】:

  • 有没有办法用 Linq 做到这一点。我不太了解这个 QueryOver API.. 至少有什么好的解释吗?
  • 这并没有说明当你想要结果时如何做。第二个查询中的内容将按照博客文章中的说明被丢弃。如果您需要急切地获取子表怎么办。
猜你喜欢
  • 1970-01-01
  • 2011-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多