web-dev-qa-db-fra.com

Des modifications conflictuelles du rôle x de la relation y ont été détectées

J'ai l'exception

Des modifications conflictuelles du rôle x de la relation y ont été détectées.

Chaque fois que j'ajoute mon entité à mon contexte

Database.MyEntitys.Add(MyEntity);

La classe MyEntity contient cette propriété:

public virtual ICollection<DetailInfo> Group { get; set; }

La classe DetailInfo est assez simple:

public class DetailInfo:BaseEntity {
    public virtual Detail Detail { get; set; }
    public decimal Total { get; set; }
    public virtual MyEntity MyEntity { get; set; }
}

Le DatabaseContext est également simple:

public class MyEntityConfiguration : EntityTypeConfiguration<MyEntity> {
    public MyEntityConfiguration() {
        HasMany(e => e.Group).WithRequired(s => s.MyEntity).WillCascadeOnDelete(true);
    }
}

public class DetailInfoConfiguration : EntityTypeConfiguration<DetailInfo> {
    public DetailInfoConfiguration() {
        HasRequired(x => x.MyEntity).WithMany(s => s.Group);
        HasRequired(x => x.Detail);
        HasKey(s => s.ID);
        ToTable("DetailInfo");
    }
}

Côté base de données, la table MyEntity possède une clé primaire pour l'ID de colonne. Le DetailInfo a également une clé primaire appelée ID. DetailInfo contient 2 FK, un pour MyEntity et un pour Detail qui est une autre entité.

Dans le scénario problématique, MyEntity est nouveau a un nouveau détail. J'attends une nouvelle entrée pour MyEntity avec un nouveau détail et avoir tous les FK correctement configurés.

Éditer:

voici l'insert:

public virtual int Insert(MyEntity myEntity) {

    if (myEntity.Group != null && myEntity.Group.Count() == 0) {
        myEntity.Group = null; 
    }

    if (myEntity.Group != null) {
        foreach (var g in myEntity.Group)
        {
         if (g.PropertyOneToOne != null) {
                if (g.PropertyOneToOne.ID == 0) {
                    myEntity.PropertyOneToOne = null;
                }
                else {
                    if (!Database.PropertyOneToOnes.Local.Any(e => e.ID == g.PropertyOneToOne.ID)) {
                        Database.PropertyOneToOnes.Attach(g.PropertyOneToOne);
                    }
                    myEntity.PropertyOneToOne = Database.PropertyOneToOnes.Local.Single(e => e.ID == g.PropertyOneToOne.ID);
                }
            }
            else {
                myEntity.PropertyOneToOne = null;
            }
        }
    }
    Database.MyEntitys.Add(myEntity);
}
34
Patrick Desjardins

Le problème est celui-ci:

MyEntity a un ID de 0 puisqu'il s'agit d'une nouvelle MyEntity. Le Groupe est également nouveau et contient une référence à MyEntity.

Ainsi, MyEntity contient une liste de Group qui contient une référence à MyEntity.

Le problème est que MyEntity.Group.MyEntity semble être "nouveau et différent" de MyEntity. Lors de l'ajout de MyEntity au contexte, il a trouvé un conflit.

Pour résoudre le problème, j'ai défini Group.MyEntity à NULL et conservez la référence de Group dans la liste de MyEntity. Lors de l'enregistrement, MyEntity référence (ID) est définie dans la table Group.

Je ne suis pas sûr que ce soit la façon la plus propre de le faire, mais le problème est finalement résolu.

46
Patrick Desjardins

Une autre solution pourrait être de configurer des données de liaison bidirectionnelles car MyEntity a besoin de Group et Group a MyEntity. Vous pouvez vous référer à ce lien pour configurer la liaison bidirectionnelle. J'espère que ça aide. Code EF 5.0 Première navigation bidirectionnelle avec l'identifiant de la clé étrangère dans l'enfant

1
Mochamad Fazar

Le problème peut également être que vous créez une nouvelle liste enfant et que vous affectez cette liste à plusieurs éléments de la liste parent, la solution est que vous devez créer une nouvelle liste enfant pour chacun des éléments parents.

0
Arvand