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为Vehicle
和ParkingBay
生成代理类,但我无法理解在第一次调用时无法清除属性的ParkingBay
属性内部发生的情况。
在Vehicle
和ParkingBay
之间是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关系和导航属性