entity framework5不清除导航属性

我在Entity Framework 5中遇到了这个奇怪的问题,我在我的一个实体中有一个导航属性,我想将其设置为null 。 但由于某种原因,我第二次调用此属性时,属性才会被清除:

 using (var db = new Entities()) { var vehicle = db.Vehicles.Single(v => v.Id == vehicleId); // After this call, ParkingBay is still set. vehicle.ParkingBay = null; // Only after this call, ParkingBay becomes null. vehicle.ParkingBay = null; db.SaveChanges(); } 

Entity Framework生成的Vehicle类如下所示:

 public partial class Vehicle { public int Id { get; set; } public System.DateTime CreatedOn { get; set; } public int CreatedBy { get; set; } public virtual ParkingBay ParkingBay { get; set; } } 

这段代码不是很ParkingBay ,并且在运行时Entity Framework为VehicleParkingBay生成代理类,但我无法理解在第一次调用时无法清除属性的ParkingBay属性内部发生的情况。

VehicleParkingBay之间是SQL Server中的正常外键关系。 这里没什么特别的。

UPDATE

ParkingBay看起来像这样:

 public partial class ParkingBay { public ParkingBay() { this.Vehicles = new HashSet(); } public int Id { get; set; } public System.DateTime CreatedOn { get; set; } public int CreatedBy { get; set; } public virtual ICollection Vehicles { get; set; } } 

这里发生了什么? 有人可以告诉我我做错了什么吗?

在查询语句( db.Vehicles.Single ... )之后,属性 null,因为您没有加载它。 为其分配另一个值不会触发延迟加载,因此此处没有任何更改。

只有在实际加载属性时,任务( 任何赋值,也用另一个对象替换它)才会生效。 如果未加载该属性,则更改跟踪器无需跟踪。

可以通过将其包含在查询中来加载该属性

 db.Vehicles.Include(v => v.ParkingBay)... 

或者通过在代码中稍后解决它,例如

 var pb = vehicle.ParkingBay; // triggers lazy loading. 

或者通过在调试器(watch或quickview)中检查它,这也会触发延迟加载。

如果您打算对导航属性本身应用任何更改,则Include推荐方法。

如下所述,清除引用导航属性的更好的方法是在模型中公开原始外键值并将其设置为null 。 在你的情况下,这将是像int? ParkingBayId int? ParkingBayId 。 当仅存在引用属性时,该模式被称为外键关联 ,而不是独立关联

实际上,您需要在将Property设置为null之前加载它。 我同意Gert Arnold的回答,只是想添加更多替代方案来做到这一点:

 db.Entry(vehicle).Reference(c => c.ParkingBay).Load(); vehicle.ParkingBay = null; 

要么

 db.Entry(vehicle).Reference(v => v.ParkingBay).CurrentValue = null; 

MSDN关系和导航属性