web-dev-qa-db-fra.com

Une relation est à l'état supprimé

Lorsque j'essaie d'effacer une collection (en appelant .Clear), je reçois l'exception suivante:

Une erreur s'est produite lors de l'enregistrement des entités qui n'exposent pas les propriétés de clé étrangère pour leurs relations. La propriété EntityEntries renverra la valeur null car une seule entité ne peut pas être identifiée comme source de l'exception. La gestion des exceptions pendant la sauvegarde peut être facilitée en exposant les propriétés de clé étrangère dans vos types d'entité. Voir l'exception interne pour plus de détails.

L'exception interne est:

Une relation de l'AssociationSet 'User_Availability' est à l'état 'Supprimé'. Compte tenu des contraintes de multiplicité, un objet "User_Availability_Target" correspondant doit également être dans l'état "Supprimé".

L'utilisateur ressemble à ceci:

....
ICollection<Availability> Availability { get; set; }

La disponibilité ressemble à ceci:

int ID { get; set; }
User User { get; set; }
DateTime Start { get; set;
DateTime End { get; set; }

La configuration est la suivante:

HasMany(x => x.Availability).WithRequired(x => x.User);
HasRequired(x => x.User).WithMany(x => x.Availability);

Le code à l'origine du problème est:

user.Availability.Clear();

J'ai envisagé d'autres solutions, telles que l'utilisation de DbSet pour supprimer des éléments, mais je ne pense pas que mon code sera aussi propre. Y a-t-il un moyen d'accomplir cela en nettoyant la collection?

28
Sam

La seule façon dont je suis conscient de le faire fonctionner consiste à définir la relation comme une identification de la relation . Il serait nécessaire d'introduire la clé étrangère de Availability à User en tant que clé étrangère dans votre modèle ...

public int ID { get; set; }
public int UserID { get; set; }
public User User { get; set; }

... et en faire une partie de la clé primaire:

modelBuilder.Entity<Availability>()
    .HasKey(a => new { a.ID, a.UserID });

Vous pouvez étendre votre mappage pour inclure cette clé étrangère (juste pour être explicite, elle n'est pas obligatoire car EF la reconnaîtra par convention):

modelBuilder.Entity<Availability>()
    .HasRequired(a => a.User)
    .WithMany(u => u.Availability)
    .HasForeignKey(a => a.UserID);

(BTW: vous ne devez configurer la relation que d’un côté. Il n’est pas nécessaire d’avoir ces deux correspondances dans votre question.)

Maintenant, vous pouvez effacer la collection avec user.Availability.Clear(); et les entités Availability seront supprimées de la base de données.

30
Slauma

Il y a un truc. Vous pouvez supprimer des entités sans utiliser DbSet spécial:

(this.dataContext as IObjectContextAdapter).ObjectContext.DeleteObject(entity);

Exécutez cette opération pour chaque élément de la collection Disponibilité avant de l’effacer. Vous n'avez pas besoin d '"identifier les relations" de cette façon.

0
poul_ko