EF 5代码优先一对多导航属性空直到上下文被刷新

时间:2013-04-27 07:09:58

标签: c# entity-framework code-first dbcontext navigation-properties

我已经看过几次这个问题,但没有解决我的问题。我创建了最简单的版本:

public class Order
{
    public int OrderId { get; set; }
    public virtual List<Item> Items { get; set; } //One to many navigation property
}

public class Item
{
    public int ItemId { get; set; }
    public string Description { get; set; }
}

订单可以有很多商品。简单。现在与EF互动:

using (var context = new TestContext())
{
    Order test = new Order();
    context.Orders.Add(test);
    context.SaveChanges();
    test.Items.Add(new Item {Description = "test"});  // no good - test.Items is null!
}

如果我这样做test.Items将为null,我无法与之交互。但是如果我“刷新”上下文一切都很好:

using (var context = new TestContext())
{
    context.Orders.Add(new Order());
    context.SaveChanges();
}

using (var context = new TestContext())
{
    Order test = context.Orders.First();
    test.Items.Add(new Item {Description = "test"});  // Happy days - test.Items is NOT null :)
}

我错过了什么?或者,每次添加具有一对多导航属性的项目时,我是否真的需要获得新的上下文?

在此先感谢哦,以色列的明智大师,知道这个主题的真相!

1 个答案:

答案 0 :(得分:3)

使用代理实体时,您需要使用DbSet.Create()创建实体(默认设置)。

实体框架代码首先将在运行时创建继承自模型类的新类。所以你没有使用你的Order类,而是继承了它。此新实现将覆盖您的虚拟导航属性以实现其他功能(例如延迟加载)。

此处需要的特定功能是注意集合何时更改。您的类不提供此类(不应该)的任何功能,但代理类可以提供。

现在,当您new Class()模型对象时,它将完全是您的对象。它不是代理实体,因此不具备附加功能。另一方面,DbSet.Create()将返回代理实体,并提升到您的班级,因此您正在使用代理。