Conflicting changes to the role x of the relationship y have been detected

Patrick Desjardins picture Patrick Desjardins · Aug 13, 2012 · Viewed 27.2k times · Source

I am having the exception

Conflicting changes to the role x of the relationship y have been detected.

Every time I add my entity to my context

Database.MyEntitys.Add(MyEntity);

The class MyEntity contain this property :

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

The DetailInfo class is pretty simple:

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

The DatabaseContext is also 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");
    }
}

On the Database side the table MyEntity has a primary key to the column ID. The DetailInfo has also a primary key called ID. DetailInfo contains 2 FK, one to MyEntity and one to Detail which is another entity.

In the problematic scenario, the MyEntity is new has a new Detail. I am expecting a new entry for MyEntity with a new Detail and having all FK correctly setup.

Edit:

here is the 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);
}

Answer

Patrick Desjardins picture Patrick Desjardins · Aug 14, 2012

The problem is this one:

MyEntity has an ID of 0 since it's a new MyEntity. The Group is also new and contain a reference to MyEntity.

So, MyEntity contains a list of Group which contain a reference back to MyEntity.

The problem is that MyEntity.Group.MyEntity seems to be "new and not the same" as MyEntity. When adding MyEntity to the context, it found a conflict.

To solve the problem I set Group.MyEntity to NULL and keep the reference of Group inside the list of MyEntity. When saving, MyEntity reference (ID) is set into the Group table.

I am not sure it's the cleanest way to do it, but the problem is finally solved.