假设我有一个实体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?
答案 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的操作顺序(相同)延迟加载的问题。)