有没有办法告诉ef 4.1应该加载实体上的属性的顺序?

时间:2011-12-01 21:03:14

标签: entity-framework-4.1

假设我有一个实体Parent和一个实体Child,这样Parent就有了一个虚拟的ICollection Children属性。在db中,这是从Child表到Parent表的简单外键。

现在说我在Parent上有一个名为Text的标量字符串属性。在Text属性的set方法期间,我想访问Children集合属性中的实例。

当EF 4.1从db重构Parent实体时(例如,由于ToList()调用),它在Text属性上调用set方法,并且在填充Children集合之前似乎总是这样做。

在调用Text标量字符串属性上的set之前,有没有办法告诉EF调用Children virutal集合属性上的set?

1 个答案:

答案 0 :(得分:2)

你应该从评论中关注@ Slauma的建议并更改代码,因为这是持久化属性的错误行为。即使以下描述有效,它也会非常容易出错,因为您始终必须以特定方式查询数据。

根据加载实体的方式,您的问题可分为多个部分。

延迟加载:

如果加载Parent and Child`是延迟加载的,则无法实现反向加载。

// Now parent is loaded
var parent = context.Parent.First(); 

// Even with lazy loading enabled and your setter accessing nav. property it
// should not load child collection because lazy loading should be temporarily
// turned off during entity materialization to avoid unexpected lazy loads

(未经测试)您可以尝试先手动加载所有子级,然后请求父级:

// Now all child for given parent are loaded
var child = context.Child.Where(c => c.Parent.Id == ...).ToList();

// Now parent is loaded and if you are lucky it configures navigation property
// to loaded child prior to evaluating your setter - I guess setter will be 
// evaluated prior to fixing navigation properties so it will not work
var parent = child[0].Parent;

显式加载会遇到同样的问题。

急切加载:

问题是相同的,它基于how Include works的方式。

因此,如果您将子项包含在父项中,则父项将首先实现。

var parent = context.Parent.Include("Child").First();

在这种情况下,反向操作最有可能无效,因为调用

var childs = context.Child.Include("Parent").Where(...).ToList();

将逐个评估记录,每条记录将包含单个子项和父项,因此我认为您第一次访问父项时您将只有单个子项,并且您将再次依赖于EF的操作顺序(相同)延迟加载的问题。)