我这里有一个基于EntityFramework的数据库,这是由代码第一种方法创建的。该数据库包含两个表,它们之间具有父子关系:
Orderlists
(基于型号“Orderlist”)Orders
(基于型号“订单”)其中,订单列表包含 ICollection<Order> Orders
,其中应该(!)列出所有相关订单。出于某种原因,它没有。
控制器的DbContext包含两个DbSets:
DbSet<Orderlist>
DbSet<Order>
另一方面,模型 Order 有两个属性(括号中的类型):
int OrderlistId
Orderlist OrderList
在新的 Order 对象的[HttpPost] Create 方法的控制器中,我通过选择适当的 Orderlist DbContext中的对象(使用正确提供/选择的ID),适当地设置新创建的 Order 对象的 OrderlistId 和 Orderlist 并添加订购到所选订单列表的 Orders 集合(如果它为null,则创建集合)。
然后我做了一个db.SaveChages();
来完成它应该做的事情。
首先从模型代码生成数据库时,关于关系,只有 OrderlistId 属性在数据表中生成一个字段。 Orderlist 的 Orders 集合和 Order 的 Orderlist 属性都不会在表中生成字段。这没关系,因为它仍然是一个有效的关系: Orderlist 的ID是PK,并且 OrderlistId 值设置正确。数据表的方案也反映了外键的关系。
现在,问题是在我的应用程序中的不同点处理数据时,关系不会恢复。当我从DbContext中选择时, Orders ICollection 始终 null 。
我的问题是:创建ICollection
对象时是否应自动填写订单 DbContext
?或者我是否必须通过迭代DbSet
的订单DbContext
手动填写它并手动将每个适当的订单添加到其相关的订单列表中?而且,如果我必须,我在哪里以及如何做到这一点?
答案 0 :(得分:1)
如果您希望实体框架按需自动加载关联实体(延迟加载),则必须使用虚拟关键字标记实体框架代码优先模型中的所有关联属性。
以下(基本)模型定义应该有效。
public class OrderList
{
public int OrderListId { get; set; }
public virtual ICollection<Order> Orders { get; set; } // note the use of virtual
}
public class Order
{
public int OrderId { get; set; }
public int OrderListId { get; set; }
public virtual OrderList OrderList { get; set; } // note the use of virtual
}
另外,请注意,在将Order添加到OrderList时,您不必在Order实体上设置关联属性。您只需将新订单添加到OrderList实体的Orders集合,如下所示:
int orderListId = 1;
OrderList orderList = context.OrderLists.Find(orderListId);
Order newOrder = new Order();
orderList.Orders.Add(newOrder);
context.SaveChanges();
或者,您可以在新订单上设置OrderListId属性,并将其添加到DbContext订单集合。
Order order = new Order();
order.OrderListId = 1;
context.Orders.Add(order);
context.SaveChanges();