not modelbuilder many framework first example dbmodelbuilder code entity-framework fluent-interface

entity framework - modelbuilder - EF6.0 "La relación no se pudo cambiar porque una o más de las propiedades de clave externa no admiten nulos"



modelbuilder entity example (4)

Si trato de eliminar una fila "hijo" siempre obtengo una excepción. Aquí hay un 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! }

Se lanza la siguiente excepción en el método SaveChanges() .

"No se pudo cambiar la relación porque una o más de las propiedades de clave foránea no admiten nulos. Cuando se realiza un cambio en una relación, la propiedad de clave foránea relacionada se establece en un valor nulo. no admite valores nulos, se debe definir una nueva relación, se debe asignar a la propiedad de clave foránea otro valor no nulo, o se debe eliminar el objeto no relacionado. "

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

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/

¿Algunas ideas? Gracias.


Debe eliminar ItemTypeItem. No es posible eliminarlo de la lista de elementos, ya que no puede existir por sí mismo, ya que tiene una clave externa no nulable que hace referencia a ItemType (ItemTypeID).

Para eliminar ItemTypeItem add

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


En el marco de la entidad 6.0, si elimina la entidad del conjunto de contexto principal, funcionará. Por ejemplo, para eliminar una entidad de inversión, haría lo siguiente:

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

Esto es diferente a intentar eliminar la entidad de su padre / propietario, como se muestra a continuación:

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

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


En la entidad 6.0 hay una diferencia entre:

context.Investments.Remove(entity);

y

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

Cuando se utiliza el primero y se habilitan las eliminaciones en cascada, 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 la reenlace / eliminación de estos objetos secundarios.


Este problema surge porque tratamos de eliminar la tabla padre. Todavía hay datos de la tabla hija presentes. Resolvemos el problema con la ayuda de Cascade Delete.

En el modelo, crea el 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();

La opción de eliminación en cascada elimina el elemento principal así como la tabla secundaria relacionada con los padres con este código simple. Hazlo probar de esta manera simple.

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