我遇到了一个奇怪的数据加载问题,我不明白,我希望有人可以向我解释发生了什么,以及如何更直接地完成我的任务。
我正在使用此问题主题中列出的技术构建网站。
我有一组对象 - 每个对象都有几个属性(名称,ID等)和其他对象的集合(ICollection<>)。所以只要查看对象树及其集合,它就像这样:
Tab
-TabRows
--Sections
---SectionRow
----Article
(因此每个选项卡都有一个或多个tabrow,每个tabrow有一个或多个部分,依此类推。每个子对象都有一个返回父对象的链接,因此每个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 = ...)执行时,我得到一个tab对象,但是TabRows集合是空的。 (它不是null,因为构造函数实例化它)。
当第二行(var tabrows = ...)执行时,tab.TabRows突然填充。 tab.TabRows.Sections为空。
当第三行执行时,tab.TabRows.Sections会突然填充。
等等。
我假设这是代表Linq的某种“延迟加载”,或者也许是其他技术之一。但我不太了解他们。
有没有办法重新编写这个,这样我就可以调用第1行,基本上所有内容都自动填充,而不必单独引用每个集合中的每个对象?
答案 0 :(得分:3)
默认启用延迟加载,禁用预先加载。实体框架允许您使用include语句提示急切加载。你的陈述会变成这样的。
var tab = db.Tabs.FirstOrDefault(t => t.TabId == id).Include("TabRows");
或包含(t => t.TabRows);
请查看this link了解详情。
在您的情况下,您还需要处理嵌套包含。这意味着您最好选择另一个模型(您的类)结构如下
Tabs -> Containing a List<TabRows> -> containing a List<Sections> etc.
然后,您需要重新编写linq,以便使用嵌套包括填充整个模型,包括嵌套实体。
作为旁注,这些内部联接中的太多可能会减慢您的查询速度,因此在可能的情况下考虑数据库端的索引视图