我得到这个错误时,我GetById()在一个实体,然后设置子实体的集合到我的新列表,来自MVC视图。
操作失败
关系是无法改变的
因为一个或多个外键
Properties是非空的。当一个
关系发生了变化
相关外键属性设置为
空值。如果外键是
不支持空值,新建
关系必须被定义
必须分配外键属性
另一个非空值或
必须删除不相关的对象。
我不太理解这句话:
这种关系无法改变
因为一个或多个外键
Properties是非空的。
我为什么要改变两个实体之间的关系?它应该在整个应用程序的生命周期内保持不变。
发生异常的代码只是简单地将集合中修改过的子类分配给现有的父类。这将有望满足取消子类,增加新的和修改。我本以为实体框架处理这个。
代码行可以提炼为:
var thisParent = _repo.GetById(1);
thisParent.ChildItems = modifiedParent.ChildItems();
_repo.Save();
如果你正在使用自动绘图器,面临以下问题是一个很好的解决方案,它为我工作
https://www.codeproject.com/Articles/576393/Solutionplusto-aplus-Theplusoperationplusfailed
因为问题是我们正在映射空导航属性,我们实际上不需要在实体上更新它们,因为它们在契约上没有改变,我们需要在映射定义上忽略它们:
ForMember(dest => dest.RefundType, opt => opt.Ignore())
所以我的代码是这样的:
Mapper.CreateMap<MyDataContract, MyEntity>
ForMember(dest => dest.NavigationProperty1, opt => opt.Ignore())
ForMember(dest => dest.NavigationProperty2, opt => opt.Ignore())
.IgnoreAllNonExisting();
这是因为子实体被标记为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将正确地将实体标记为已删除。
如果你正在使用自动绘图器,面临以下问题是一个很好的解决方案,它为我工作
https://www.codeproject.com/Articles/576393/Solutionplusto-aplus-Theplusoperationplusfailed
因为问题是我们正在映射空导航属性,我们实际上不需要在实体上更新它们,因为它们在契约上没有改变,我们需要在映射定义上忽略它们:
ForMember(dest => dest.RefundType, opt => opt.Ignore())
所以我的代码是这样的:
Mapper.CreateMap<MyDataContract, MyEntity>
ForMember(dest => dest.NavigationProperty1, opt => opt.Ignore())
ForMember(dest => dest.NavigationProperty2, opt => opt.Ignore())
.IgnoreAllNonExisting();
我今天遇到了这个问题,想分享我的解决方案。在我的例子中,解决方案是在从数据库中获取Parent之前删除Child项。
以前我是这样做的代码如下。然后我将得到这个问题中列出的相同错误。
var Parent = GetParent(parentId);
var children = Parent.Children;
foreach (var c in children )
{
Context.Children.Remove(c);
}
Context.SaveChanges();
对我来说,有效的方法是先获取子项,使用parentId(外键),然后删除这些项。然后我可以从数据库中获取父元素,在这一点上,它应该不再有任何子元素,我可以添加新的子元素。
var children = GetChildren(parentId);
foreach (var c in children )
{
Context.Children.Remove(c);
}
Context.SaveChanges();
var Parent = GetParent(parentId);
Parent.Children = //assign new entities/items here