35

如果我尝试删除“子”行,我总是会遇到异常。这是一个片段:

using (var context = new CompanyContext())
{
    ItemType itemType = context.ItemTypes.FirstOrDefault(i => i.Name == "ServerType");
    ItemTypeItem itemTypeItem = itemType.Items.FirstOrDefault(i => i.Name == "DatabaseServer");
    itemType.Items.Remove(itemTypeItem);
    context.SaveChanges(); <=== exception!
}

SaveChanges()方法引发以下异常。

“无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性设置为空值。如果外键确实不支持空值,必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。”

实体配置

  public class ItemTypeConfiguration : NamedEntityConfiguration<ItemType>
  {
    public ConfigurationColumn ParentIDColumn;
    public ConfigurationColumn ValidationPatternColumn;
    public ItemTypeConfiguration() : base()
    {
      ParentIDColumn = new ConfigurationColumn() { Name = "ParentID", Ordinal = base.LastOrdinalPosition + 1 };
      ValidationPatternColumn = new ConfigurationColumn() { Name = "ValidationPattern", Length = 1024, Ordinal=base.LastOrdinalPosition + 2};
      this.Property(t => t.ParentID)
        .HasColumnName(ParentIDColumn.Name)
        .HasColumnOrder(ParentIDColumn.Ordinal);
      this.HasOptional(t => t.Parent).WithMany().HasForeignKey(u => u.ParentID).WillCascadeOnDelete(false);
      this.Property(t => t.ValidationPattern)
        .HasColumnName(ValidationPatternColumn.Name)
        .HasColumnOrder(ValidationPatternColumn.Ordinal)
        .HasMaxLength(ValidationPatternColumn.Length);
    }
...


  public class ItemTypeItemConfiguration : NamedEntityConfiguration<ItemTypeItem>
  {
    public ConfigurationColumn ItemTypeIDColumn;
    public ItemTypeItemConfiguration() : base()
    {
      ItemTypeIDColumn = new ConfigurationColumn(){Name="ItemTypeID", IsRequired=true, Ordinal= base.LastOrdinalPosition+1};
      this.Property(t => t.ItemTypeID)
        .HasColumnName(ItemTypeIDColumn.Name)
        .HasColumnOrder(ItemTypeIDColumn.Ordinal);
      this.HasRequired(t => t.ItemType).WithMany(t=>t.Items).HasForeignKey(u => u.ItemTypeID).WillCascadeOnDelete(true);
    }
...

在此处输入图像描述

我找到了博客,但我没有“DeleteObject”方法。

http://blog.clicdata.com/2013/07/04/the-operation-failed-the-relationship-could-not-be-changed-because-one-or-more-of-the-foreign-key-属性是不可为空的/

有任何想法吗?谢谢你。

4

5 回答 5

53

您需要删除 ItemTypeItem。不能仅将其从 Items 列表中删除,因为它不能单独存在,因为它具有引用 ItemType (ItemTypeID) 的不可为空的外键。

要删除 ItemTypeItem 添加

context.Entry(itemTypeItem).State = EntityState.Deleted;
于 2013-10-11T19:50:32.290 回答
51

在实体框架 6.0 中,如果您从主上下文集中删除实体,它将起作用。例如,要删除投资实体,您将执行以下操作:

context.Investments.Remove(entity);
context.SaveChanges();

这与尝试从其父/所有者中删除实体不同,如下所示:

bankAccount.Investments.Remove(entity);
context.SaveChanges();

这将引发上述关系无法更改的异常。希望这可以帮助。

于 2014-07-24T17:16:58.717 回答
24

在实体 6.0 中,有以下区别:

context.Investments.Remove(entity);

context.Entry(entity).State = EntityState.Deleted;

启用第一个和级联删除时,EF 将在内部执行子集合的必要删除。使用第二个选项时,EF 不会处理必要的删除,而是让您处理这些子对象的重新绑定/删除。

于 2015-11-10T10:36:19.747 回答
1

出现这个问题是因为我们尝试删除父表仍然存在子表数据。我们在级联删除的帮助下解决了这个问题。

在 dbcontext 类中的模型 Create 方法中。

 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();

级联删除选项使用此简单代码删除父表以及与父相关的子表。让它以这种简单的方式尝试。

删除用于删除数据库中记录列表的范围谢谢

于 2017-01-30T12:35:53.620 回答
0

描述错误发生原因的其他答案是正确的,但实际上可以让 EF.Remove在父对象的子对象集合上调用时完全删除子对象,您不需要直接转到子实体的表中数据库上下文并从中删除。

要使其正常工作,您需要设置一个识别关系,如本答案中所述

于 2021-08-02T08:54:49.157 回答