EF6.0 " La relación no se pudo cambiar porque una o más de las propiedades de la clave foránea no son nullables"


Si intento eliminar una fila "hijo" siempre obtengo una excepción. He aquí un juego de francotiradores:

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

La siguiente excepción se lanza en el método SaveChanges().

"La relación no se pudo cambiar porque una o más de las propiedades de clave foránea no son nullables. Cuando se realiza un cambio en una relación, la propiedad de clave externa relacionada se establece en un valor null. Si la clave foránea no admite valores nulos, se debe definir una nueva relación, la propiedad se le asignará otro valor no nulo, o el objeto no relacionado debe eliminarse."

Configuración de la entidad

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

introduzca la descripción de la imagen aquí

Encontré el blog pero no tengo el método "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-properties-is-non-nullable/

¿Alguna idea? Agradecer.

Author: Nico, 2013-10-11

4 answers

Es necesario eliminar el ItemTypeItem. No es posible simplemente eliminarlo de la lista de elementos, ya que no puede existir por sí mismo, porque tiene una clave foránea no anulable que hace referencia a ItemType (ItemTypeID).

Para eliminar el ItemTypeItem añadir

context.Entry(itemTypeItem).State = EntityState.Deleted;
 46
Author: Olav Nybø,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-11 19:50:32

En entity framework 6.0 si elimina la entidad del conjunto de contexto principal, funcionará. Por ejemplo, para eliminar una entidad de inversión, debe hacer lo siguiente:

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

Esto es diferente a intentar eliminar la entidad de su padre / propietario, como lo siguiente:

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

Esto arrojará la relación no se pudo cambiar excepción listada anteriormente. Espero que esto ayude.

 41
Author: Gerry Polucci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-04 17:25:52

En la entidad 6.0 hay una diferencia entre:

context.Investments.Remove(entity);

Y

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

Cuando se utilizan las eliminaciones primera y en cascada están habilitadas, EF realizará internamente las eliminaciones necesarias de las colecciones secundarias. Al usar la segunda opción, EF no manejará las eliminaciones necesarias, pero le permitirá manejar el rebinding/borrado de estos objetos secundarios.

 17
Author: Eddieke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-10 10:36:19

Este problema surge porque tratamos de eliminar la tabla padre todavía los datos de la tabla hijo están presentes. Resolvemos el problema con la ayuda de cascade delete.

En el modelo Crear método en la clase dbcontext.

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

Después de eso, En nuestra llamada API

var JobList = Context.Job                       
          .Include(x => x.JobSportsMappings)                                     .ToList();
Context.Job.RemoveRange(JobList);
Context.SaveChanges();

Cascade delete opción eliminar el padre y la tabla hijo relacionada con el padre con este simple código. Haz que lo intente de esta manera sencilla.

Eliminar Rango que se utiliza para eliminar la lista de registros en la base de datos Gracias

 1
Author: Sowmiya V,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-30 12:35:53