我得到这个错误时,我GetById()在一个实体,然后设置子实体的集合到我的新列表,来自MVC视图。
操作失败
关系是无法改变的
因为一个或多个外键
Properties是非空的。当一个
关系发生了变化
相关外键属性设置为
空值。如果外键是
不支持空值,新建
关系必须被定义
必须分配外键属性
另一个非空值或
必须删除不相关的对象。
我不太理解这句话:
这种关系无法改变
因为一个或多个外键
Properties是非空的。
我为什么要改变两个实体之间的关系?它应该在整个应用程序的生命周期内保持不变。
发生异常的代码只是简单地将集合中修改过的子类分配给现有的父类。这将有望满足取消子类,增加新的和修改。我本以为实体框架处理这个。
代码行可以提炼为:
var thisParent = _repo.GetById(1);
thisParent.ChildItems = modifiedParent.ChildItems();
_repo.Save();
我使用了Mosh的解决方案,但我不清楚如何在代码中正确地实现组合键。
这就是解决方案:
public class Holiday
{
[Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int HolidayId { get; set; }
[Key, Column(Order = 1), ForeignKey("Location")]
public LocationEnum LocationId { get; set; }
public virtual Location Location { get; set; }
public DateTime Date { get; set; }
public string Name { get; set; }
}
这是因为子实体被标记为Modified而不是Deleted。
当执行parent. remove (Child)时,EF对子实体所做的修改只是将其父实体的引用设置为null。
当异常发生时,在执行SaveChanges()后,你可以通过在Visual Studio的即时窗口中输入以下代码来检查子对象的EntityState:
_context.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Modified).ElementAt(X).Entity
其中X应替换为删除的实体。
如果你不能访问ObjectContext来执行_context.ChildEntity.Remove(child),你可以通过使外键成为子表中主键的一部分来解决这个问题。
Parent
________________
| PK IdParent |
| Name |
|________________|
Child
________________
| PK IdChild |
| PK,FK IdParent |
| Name |
|________________|
这样,如果你执行parent.Remove(child), EF将正确地将实体标记为已删除。
我也解决了我的问题与Mosh的答案,我认为PeterB的答案是有点,因为它使用枚举作为外键。请记住,在添加这段代码之后,您将需要添加一个新的迁移。
我也可以推荐这篇博客的其他解决方案:
http://www.kianryan.co.uk/2013/03/orphaned-child/
代码:
public class Child
{
[Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Heading { get; set; }
//Add other properties here.
[Key, Column(Order = 1)]
public int ParentId { get; set; }
public virtual Parent Parent { get; set; }
}
出现这个问题是因为我们试图删除父表,但仍然存在子表数据。
我们利用级联删除来解决这个问题。
在模型中创建dbcontext类中的方法。
modelBuilder.Entity<Job>()
.HasMany<JobSportsMapping>(C => C.JobSportsMappings)
.WithRequired(C => C.Job)
.HasForeignKey(C => C.JobId).WillCascadeOnDelete(true);
modelBuilder.Entity<Sport>()
.HasMany<JobSportsMapping>(C => C.JobSportsMappings)
.WithRequired(C => C.Sport)
.HasForeignKey(C => C.SportId).WillCascadeOnDelete(true);
之后,在我们的API调用中
var JobList = Context.Job
.Include(x => x.JobSportsMappings) .ToList();
Context.Job.RemoveRange(JobList);
Context.SaveChanges();
级联删除选项删除父表以及与父相关的子表,使用这个简单的代码。用这个简单的方法试试。
删除范围用于删除数据库中的记录列表
谢谢