【发布时间】:2021-03-17 21:52:03
【问题描述】:
所以前言:我有一对模型,一个被定义为“父”,它有自己的 ID、属性和子组件的字段:
public class SearchDesign
{
[Key]
[DataMember]
public int Id {get; set;}
// ... more properties
[DataMember]
public virtual ICollection<SearchComponent> SearchComponents { get; set; }
}
组件本身是SearchDesign 的子级,并且设置为也可以表示为树。
public class SearchComponent
{
[Key]
[DataMember]
public int Id { get; set; }
[Key]
[DataMember]
public int SearchDesignID { get; set; }
[Required]
[DataMember]
public int Order { get; set; }
[DataMember]
public int? ParentID { get; set; }
// ... more properties
[DataMember]
public virtual SearchDesign SearchDesign { get; set; }
[DataMember]
public virtual SearchComponent ParentComponent { get; set; }
[DataMember]
public virtual ICollection<SearchComponent> ChildComponents { get; set; }
}
模型的这些特定部分设置在 DBContext 中,如下所示...
modelBuilder.Entity<SearchComponent>()
.HasKey(sc => new { sc.Id, sc.SearchDesignID });
modelBuilder.Entity<SearchComponent>()
.HasMany(parent => parent.ChildComponents)
.WithOne(child => child.ParentComponent)
.HasForeignKey(parent => new { parent.ParentID, parent.SearchDesignID })
.IsRequired(false)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<SearchComponent>()
.HasOne(sc => sc.SearchDesign)
.WithMany(sd => sd.SearchComponents)
.HasForeignKey(sc => sc.SearchDesignID)
.IsRequired(false);
所以有一点我尝试通过 API 执行更新函数,该 API 调用一个函数,该函数将覆盖我们数据库中现有实体的特征。在执行此操作的过程中,我们从设计中“移除”相关组件,然后以反映在来自请求的输入中的状态重新添加它们:
//Update case.
design = design.Clone(); //function that un-links the entity from EF core by using Newtonsoft to de-serialize and then re-serialize it.
SearchDesign existing = LoadDesign(design.Id);
if (existing == null)
{
throw new ArgumentOutOfRangeException();
}
else
{
existing.Name = design.Name;
...
//Remove and re-add.
DBContext.SearchComponents.RemoveRange(existing.SearchComponents); //THIS throws the error.
foreach (var component in design.SearchComponents)
{
component.SearchDesign = existing;
}
DBContext.SearchComponents.AddRange(design.SearchComponents);
}
问题是,当我尝试RemoveRange(我重申)尝试删除依赖元素时,它会抛出此错误:
System.InvalidOperationException : 实体之间的关联 带有键值的“SearchDesign”和“SearchComponent” '{SearchDesignID: 7}' 已被切断,但关系是 标记为“必需”或隐含需要,因为外键 不可为空。如果依赖/子实体应该在什么时候被删除 断开所需的关系,然后设置要使用的关系 级联删除。
我的直觉让我相信这可能与 SearchComponent 结构上的父/子循环有关,但错误似乎表明这是与设计/组件链接有关的问题?如果确实如此,那么这个错误就没有任何意义,因为我试图删除依赖/子实体,而不是父实体,并且我不能完全将 SearchDesignID 设置为 null,因为这是元素的一部分键。
我们将不胜感激 EF Core 专家的任何建议,谢谢!
【问题讨论】:
-
这里的问题是:“隐含需要,因为外键不可为空”。
SearchDesignID必须可以为空才能使关系成为可选。 -
对,但是
SearchComponent(依赖实体)上的SearchDesignID本质上并不意味着可以为空。如果没有附加的设计,它就不应该存在。它还用作具有自己 ID 的元素的复合键,我不确定 SQL 表中元素的键(或构成该键的东西)是否可以为空?