Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF6.0 "The relationship could not be changed because one or more of the foreign-key properties is non-nullable"

If I try to delete a "child" row I always get an exception. Here is a snipset:

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!
}

The following exception is thrown on the SaveChanges() method.

"The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted."

Entity Configuration

  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);
    }
...

enter image description here

I found the blog but I don't have the "DeleteObject" method.

http://blog.clicdata.com/2013/07/04/the-operation-failed-the-relationship-could-not-be-changed-because-one-or-more-of-the-foreign-key-properties-is-non-nullable/

Any ideas? Thank you.

like image 988
Max Avatar asked Oct 11 '13 19:10

Max


3 Answers

You need to delete the ItemTypeItem. It is not possible to just remove it from the Items list as it cannot exist by itself, because it has a non-nullable foreign key referencing ItemType (ItemTypeID).

To delete the ItemTypeItem add

context.Entry(itemTypeItem).State = EntityState.Deleted;
like image 114
Olav Nybø Avatar answered Nov 12 '22 16:11

Olav Nybø


In the entity framework 6.0 if you remove the entity from the main context set it will work. For example to remove an investment entity you would do the following:

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

This is different than attempting to remove the entity from its parent/owner, as the following:

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

This will throw the relationship could not be changed exception listed above. Hope this helps.

like image 38
Gerry Polucci Avatar answered Nov 12 '22 14:11

Gerry Polucci


In entity 6.0 there is a difference between:

context.Investments.Remove(entity);

and

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

When using the first and cascading deletes are enabled, EF will internally perform the necessary deletes of child collections. When using the second option, EF will not handle the necessary deletes, but let you handle the rebinding/deletion of these child objects.

like image 36
Eddieke Avatar answered Nov 12 '22 15:11

Eddieke