EF6.0"由于一个或多个外键属性不可为空,因此无法更改关系"

Max*_*Max 30 entity-framework fluent-interface

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

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!
}
Run Code Online (Sandbox Code Playgroud)

SaveChanges()方法抛出以下异常.

"由于一个或多个外键属性不可为空,因此无法更改关系.当对关系进行更改时,相关的外键属性将设置为空值.如果外键是如果不支持空值,则必须定义新关系,必须为foreign-key属性分配另一个非空值,或者必须删除不相关的对象."

实体配置

  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);
    }
...
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我找到了博客,但我没有"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-属性 - 是 - 不可为空/

有任何想法吗?谢谢.

Ola*_*ybø 50

您需要删除ItemTypeItem.不可能只将它从Items列表中删除,因为它本身不存在,因为它有一个不可为空的外键引用ItemType(ItemTypeID).

删除ItemTypeItem添加

context.Entry(itemTypeItem).State = EntityState.Deleted;
Run Code Online (Sandbox Code Playgroud)

  • 这很奇怪,因为我能够在不执行EntityState.Added的情况下添加项目...但是那个有用的人,谢谢!现在我需要找出如何更改我的存储库以实现相同的功能.我只是直接从上下文中测试过.EF就是这样一个黑盒子,需要学习! (3认同)
  • 我只有在阅读下面 @Gerry 的答案后才明白这个答案..,关键是将其从“上下文”而不是从实体父级中删除...... (2认同)

小智 45

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

context.Investments.Remove(entity);
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

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

bankAccount.Investments.Remove(entity);
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

这将抛出关系无法更改上面列出的异常.希望这可以帮助.


小智 21

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

context.Investments.Remove(entity);
Run Code Online (Sandbox Code Playgroud)

context.Entry(entity).State = EntityState.Deleted;
Run Code Online (Sandbox Code Playgroud)

当启用第一个和级联删除时,EF将在内部执行必要的子集合删除.使用第二个选项时,EF不会处理必要的删除操作,但允许您处理这些子对象的重新绑定/删除.

  • 救了我的一天.我已经配置了正确的级联删除,但我得到了相同的异常.更令人惊讶的是,一个全面的SQL Server作为后端的绿色单元测试证明,级联删除开始了.这个评论让我思考并帮助我解决了这个问题:context.Set <T> .Remove(entity)是首选的实体是在此上下文实例之前加载的,而context.Entry(entity).State = Deleted在提供密钥和构建存根实体时起作用. (2认同)

归档时间:

查看次数:

40072 次

最近记录:

8 年 前