在我的EF4.3代码中(但是与EF生成的数据库相比,显式设计数据库)存在以下问题。从集合中删除数据库中的项目(EF 4.3)
我有一个实体“WorkPlan”,它可以包含一对多的“休息”实体。在模型中,工作计划具有ICollection,但Break并不知道工作计划。
这是一个聚合关系。 “休息”不能超出工作计划的范围。
我希望发生的是,当我删除从断裂的工作计划的集合休息,该休息要在数据库中保存更改时删除:
[Test]
public void ShouldRemoveBreakInDatabase()
{
// Setup
var workPlan = WorkPlanBuilder.Build(x => x.AddBreak());
Save(workPlan);
// Exercise
var exerciseContext = CreateDataContext();
workPlan = exerciseContext.WorkPlans.Single();
workPlan.RemoveBreak(workPlan.Breaks.Single());
exerciseContext.SaveChanges();
// Verify
var actual = SqlHelper.ExecuteScalar("select count(*) from Breaks");
Assert.That(actual, Is.EqualTo(0));
}
然而,调用SaveChanges()调用的结果在以下情况除外:
System.Data.Entity.Infrastructure.DbUpdateException:保存不为他们的关系暴露的外键 性实体出错 。 EntityEntries属性 将返回null,因为无法将单个实体标识为异常的源 。通过在您的实体类型中公开外键属性,可以更轻松地处理异常,同时保存 。有关详细信息,请参阅 InnerException。
----> System.Data.UpdateException: 更新条目时发生错误。有关详细信息,请参阅内部例外 。
----> System.Data.SqlClient.SqlException:不能 将值NULL插入到'WorkPlan_Id'列中,表 'ActivityStore.dbo.Breaks';列不允许有空值。更新失败。 该声明已被终止。
看起来很清楚,当从WorkPlan的集合中删除Break时,EF假定它应该在数据库中将WorkPlan_Id字段设置为null,但该字段不可为空。
添加以下到我的数据方面:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<WorkPlan>().HasMany(x => x.Breaks).WithRequired();
}
导致不同的例外:
System.Data.Entity.Infrastructure.DbUpdateException:错误 同时节省不发生实体为其关系公开外键 属性。 EntityEntries属性 将返回null,因为无法将单个实体标识为异常的源 。通过在您的实体类型中公开外键属性,可以更轻松地处理异常,同时保存 。有关详细信息,请参阅 InnerException。
----> System.Data.UpdateException: 来自“WorkPlan_Breaks”AssociationSet的关系处于 “已删除”状态。考虑到多重性限制,相应的 “WorkPlan_Breaks_Target”也必须处于“已删除”状态。
有没有一种简单的方法来实现它?