我已经看过几次这个问题,但没有解决我的问题。我创建了最简单的版本:
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 :)
}
我错过了什么?或者,每次添加具有一对多导航属性的项目时,我是否真的需要获得新的上下文?
在此先感谢哦,以色列的明智大师,知道这个主题的真相!
答案 0 :(得分:3)
使用代理实体时,您需要使用DbSet.Create()
创建实体(默认设置)。
实体框架代码首先将在运行时创建继承自模型类的新类。所以你没有使用你的Order
类,而是继承了它。此新实现将覆盖您的虚拟导航属性以实现其他功能(例如延迟加载)。
此处需要的特定功能是注意集合何时更改。您的类不提供此类(不应该)的任何功能,但代理类可以提供。
现在,当您new Class()
模型对象时,它将完全是您的对象。它不是代理实体,因此不具备附加功能。另一方面,DbSet.Create()
将返回代理实体,并提升到您的班级,因此您正在使用代理。