EF 4.1 POCO在Db.Entry()之后访问导航属性

时间:2011-07-06 12:11:46

标签: asp.net-mvc-3 entity-framework-4.1 poco dbcontext

问题

不确定这样做的正确方法是......我有一个简单的课程:

public partial class Event
{
    public int Id { get; set; }
    public string Description { get; set; }
    public int? PreviousEventId { get; set; }
    public virtual Event PreviousEvent { get; set; }
}

在我的MVC 3项目中,我有一个表单,用于编辑事件描述和(可选)从下拉列表中选择上一个事件。表单被提交到一个操作,并像往常一样使用MVC 3,自动映射到Event

[HttpPost]
public ActionResult SaveEvent(Event myEvent)
{
    if (ModelState.IsValid)
    {
        Db.Entry(myEvent).State = EntityState.Modified;
        // do some additional checks
        Db.SaveChanges();
    }
}

我想在保存实体之前进行一些需要访问PreviousEvent的额外验证。但是,当我在上面的代码中访问它时,导航属性始终为null。这是有道理的 - 表单直接映射到我的POCO类Event,而不是映射到由EF创建的代理。

问题

有没有办法将修改后的Event替换为其代理,以便EF可以帮助加载其导航属性?我能做到:

Db.Entry(myEvent).Reference(e => e.PreviousEvent).Load();
// do some checking on myEvent.PreviousEvent

...但是以这种方式加载所有导航属性似乎很平常(这个类比显示的要多得多),我希望EF有更好的方法来做到这一点。确实是吗?

1 个答案:

答案 0 :(得分:1)

您要求的是对传递给您的操作的实体实例的延迟加载的支持。通过EF创建的动态代理(=动态创建的派生类型)提供延迟加载。一旦在没有代理的情况下创建实例,它就不能使用延迟加载,并且无法将其更改为允许它!

要创建支持延迟加载的实例,您必须使用:

Event event = context.Events.Create();

但默认模型绑定器只使用默认构造函数。

Event event = new Event();

因此,如果您希望支持延迟加载,则必须为此编写自己的模型绑定器。

一旦你有代理实例,你可以简单地将实例附加到上下文,延迟加载应该适合你。