web-dev-qa-db-fra.com

EF6.0 "La relation n'a pas pu être modifiée car une ou plusieurs des propriétés de clé étrangère ne peuvent pas être annulées"

Si j'essaie de supprimer une ligne "enfant", j'obtiens toujours une exception. Voici 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!
}

L'exception suivante est levée sur la méthode SaveChanges().

"La relation n'a pas pu être modifiée car une ou plusieurs propriétés de clé étrangère ne peuvent pas être annulées. Lorsqu'une modification est apportée à une relation, la propriété de clé étrangère associée est définie sur une valeur nulle. Si la clé étrangère ne ne prend pas en charge les valeurs nulles, une nouvelle relation doit être définie, la propriété de clé étrangère doit recevoir une autre valeur non nulle ou l'objet non lié doit être supprimé. "

Configuration d'entité

  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

J'ai trouvé le blog mais je n'ai pas la méthode "DeleteObject".

http://blog.clicdata.com/2013/07/04/the-operation-failed-the-relationship-could-not-be-changed-because-one-or-more-of-the- propriétés-clés-étrangères-est-non-nullable /

Des idées? Merci.

30
Max

Vous devez supprimer le ItemTypeItem. Il n'est pas possible de simplement le supprimer de la liste des éléments car il ne peut pas exister par lui-même, car il possède une clé étrangère non nullable référençant ItemType (ItemTypeID).

Pour supprimer le ItemTypeItem, ajoutez

context.Entry(itemTypeItem).State = EntityState.Deleted;
50
Olav Nybø

Dans l'entité Framework 6.0, si vous supprimez l'entité de l'ensemble de contexte principal, cela fonctionnera. Par exemple, pour supprimer une entité d'investissement, vous devez procéder comme suit:

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

Ceci est différent de la tentative de suppression de l'entité de son parent/propriétaire, comme suit:

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

Cela lèvera la relation n'a pas pu être modifiée exception énumérée ci-dessus. J'espère que cela t'aides.

45
Gerry Polucci

Dans l'entité 6.0, il y a une différence entre:

context.Investments.Remove(entity);

et

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

Lorsque vous utilisez la première et que les suppressions en cascade sont activées, EF effectuera en interne les suppressions nécessaires des collections enfants. Lorsque vous utilisez la deuxième option, EF ne gère pas les suppressions nécessaires, mais vous permet de gérer la reliure/suppression de ces objets enfants.

21
Eddieke

Ce problème se produit car nous essayons de supprimer la table parent, mais les données de la table enfant sont toujours présentes. Nous résolvons le problème à l'aide de la suppression en cascade.

Dans le modèle Create, méthode dans la classe 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);

Après cela, dans notre appel API

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

L'option de suppression en cascade supprime le parent ainsi que la table enfant liée au parent avec ce code simple. Faites-le essayer de cette manière simple.

Supprimer la plage qui a utilisé pour supprimer la liste des enregistrements dans la base de données Merci

1
Sowmiya V