【发布时间】:2016-07-15 12:29:44
【问题描述】:
我已经声明了一个这样的实体(实际的类显然也有一个 ID 属性,映射完成等,但这不是问题,所以我在这里跳过它):
public class Parent
{
public virtual ICollection<Child> Children {get; set;}
}
这很完美:
public class Consumer
{
void DoBusiness()
{
using (var ctx = new MyDbContext())
{
var entity = ctx.Parents.Find(keyOfParent);
// This is as expected: entity.Children refers to a collection which
// Entity Framework has assigned, a collection which supports lazy loading.
}
}
}
现在我更改要保护的 Children 集合的可见性:
public class Parent
{
protected virtual ICollection<Child> Children {get; set;}
}
这带来了意想不到的结果:
public class Consumer
{
void DoBusiness()
{
using (var ctx = new MyDbContext())
{
var entity = ctx.Parents.Find(keyOfParent);
// This is NOT as expected: entity.Children is null. I would expect, that it
// had been referring to a collection which Entity Framework would have been
// assigning, a collection which should support lazy loading.
}
}
}
此外,如果我处于受保护儿童的情况,请尝试通过以下方式显式加载儿童:
ctc.Entry(entity).Collection(x => x.Children)
然后我得到这个异常:
“Parent”类型的属性“Children”不是导航属性。Reference 和 Collection 方法只能与导航属性一起使用。请使用 Property 或 ComplexProperty 方法。
因此:为了使用 Entity Framework 获得受保护的导航属性,我应该具体做什么?
【问题讨论】:
-
你到底为什么要这么做? EF 中的“实体”只不过是数据库表、记录和关系的对象表示。它们不应该包含业务逻辑。因此,它们和它们的成员应该是可见的,以便在查询中使用。示例代码
ctc.Entry(entity).Collection(x => x.Children)只能从违反这些原则的Parent类内部运行。 -
因为与示例中的 Children 相对应的具体属性将仅通过反射使用,因此您给出的有关查询的基本考虑不适用。关于您的编码评论:是的,很明显,但它强调实体框架在属性受到保护后不会将其视为导航属性。请问您也有一些贡献信息吗?
-
如果属性标记为
protected,框架将如何使用该属性并加载它?它无法“看到”它;只有子类可以。 -
通过实际实现它,如下所示:owencraig.com/…。当我加载 Parent 时,我的 Children 集合仍然为空,这就是我觉得奇怪的地方。你知道怎么解决吗?
-
链接失效了,能重新发一下吗?建设性地说,我尝试设置这样的模型和
Children,并且能够使其既懒惰又显式加载。Child类中是否有类似Parent Parent { get; set; }的反向导航属性?也受到保护?
标签: c# entity-framework