1

我在数据加载方面遇到了一个奇怪的问题,我不明白,我希望有人可以向我解释发生了什么,也许如何更直接地完成我的任务。

我正在使用此问题主题中列出的技术构建网站。

我有一组对象——每个对象都有几个属性(名称、ID 等)和其他对象的集合(ICollection<>)。所以只要看看对象树及其集合,它看起来像这样:

Tab
-TabRows
--Sections
---SectionRow
----Article

(所以每个选项卡有一个或多个 tabrow,每个 tabrow 有一个或多个 section,等等。每个子对象都有一个返回父对象的链接,所以每个 sectionrow 都有一个 SectionID,每个 Section 都有一个 TabRowID,等等)

好的,鉴于该结构,请考虑以下代码:

// GET api/Tab/5
public Tab GetTab(int id)
{
    var tab = db.Tabs.FirstOrDefault(t => t.TabId == id);
    var tabrows = db.TabRows.ToList();
    var sections = db.Sections.ToList(); // This makes the tabRow.Sections populate
    var sectionrows = db.SectionRows.ToList();
    var articles = db.Articles.ToList();
    return tab;
}

这就是发生的事情。当第一行 (var tab =...) 执行时,我得到一个选项卡对象,但 TabRows 集合为空。(它不为空,因为构造函数实例化了它)。

当第二行 (var tabrows =...) 执行时,tab.TabRows 突然填充。tab.TabRows.Sections 是空的。

当第三行执行时,tab.TabRows.Sections 突然填充。

等等。

我假设这是代表 Linq 的某种“延迟加载”,或者可能是其他技术之一。但我不太了解他们,无法弄清楚。

有没有办法重写它,这样我就可以调用第 1 行,基本上让所有内容自动填充,而不必单独引用每个集合中的每个对象?

4

1 回答 1

3

默认情况下启用延迟加载并禁用急切加载。实体框架允许您使用 include 语句提示预先加载。你的陈述会变成这样。

 var tab = db.Tabs.FirstOrDefault(t => t.TabId == id).Include("TabRows");

或作为 Include(t => t.TabRows);

查看此链接以获取更多信息。

在您的情况下,您还需要处理嵌套包含。这意味着您最好采用如下结构的另一个模型(您的课程)

 Tabs -> Containing a List<TabRows> -> containing a List<Sections> etc. 

然后,您需要重新编写 linq,以便它使用嵌套包含填充整个模型,包括嵌套实体。

附带说明一下,太多的内部连接可能会减慢您的查询速度,因此如果可能,请考虑在数据库端使用索引视图

于 2013-05-23T04:23:40.610 回答