`Attaching an entity of type failed...` exception while trying to update a class in EF and with a generic repository

c# ef-code-first entity-framework entity-framework-6

Question

I'm using Entity Framework. I want to load an entity, edit it, and save the changes back in the DB. But no matter if I've edited a foreign key property or a simple property, EF gives me the following error:

Attaching an entity of type 'ClassX' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

Please note that ClassX is not a direct virtual property of the class that I'm trying to update, instead it's a virtual property in some of the other classes that my class has navigation properties to them.

I've read some related issues. But I didn't really get how I should apply them to my own problem, since I'm using a generic repository as posted below.

public class GenericRepository<T>  where T : class
{
    private EFDbContext context = new EFDbContext();
    public IEnumerable<T> GetAll()
    {
        return context.Set<T>();
    }
    public void Insert(T entity)
    {
        context.Set<T>().Add(entity);
        context.SaveChanges();
    }
    public void Update(T entity)
    {
        context.Entry(entity).State = System.Data.Entity.EntityState.Modified;
        context.SaveChanges();
    }
 //removed for brevity
}

I've encountered another problem related to virtual properties and I was advised to use ViewModels and Object to Object mapping.

As far as I got it, there's 3 options:

  1. Use ViewModels and object-to-object mapping. I'm not going with this one, it was really painful since o2o mapping libraries have lots of bugs.
  2. Somehow uses reference. But I can't do that since the repository is generic. Maybe I should use reflection API for that?
  3. Delete all virtual properties. It is actually an option, since they're creating more problems than they solve.

Can anyone please explain why this problem happens and what's the easiest way to solve it?

1
2
5/23/2017 12:32:47 PM

Popular Answer

When you set the State of an entity to Modified it also attaches all children (entities referenced by navigation properties) with State == EntityState.Unchanged. If your context already has entities with the same key, it will raise that error.

If you want those entities to be ignored, there are a few options I can think of:

  1. Create a new data context within Update, and don't worry about the children entities because with EntityState.Unchanged, when you call SaveChanges, they'll be ignored. This probably doesn't make sense if you're using some kind of Repository Pattern.
  2. Go through the navigation properties you don't want to attach and set to null before setting State = EntityState.Modified
  3. After setting State = EntityState.Modified, for child entities you want to ignore, set State = EntityState.Detached

Edit

It would also be good to figure out why the context would end up with multiple child entities with the same key in the first place.

4
5/23/2015 4:05:15 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow