'entity of the same type already has the same primary key value' error using AutoMapper

21,025

This might just be me being unaware of some features, but your update function looks funky to me. I don't see how it would associate your new user with the existing one in the db.

This is how I would approach it.

public void Update(UserModel userModel)
{
    var user = db.Users.Find(userModel.UserId);
    Mapper.Map(userModel, user);
    db.SaveChanges();
}

or, if you prefer to do it like your second update function does

public void Update(UserModel userModel)
{
    Mapper.Map(userModel, updatingUser);
    db.Entry(updatingUser).State = EntityState.Modified;
    db.SaveChanges();
}
Share:
21,025

Related videos on Youtube

alite
Author by

alite

Updated on March 31, 2020

Comments

  • alite
    alite about 4 years

    When I use AutoMapper, this Error occured:

    Attaching an entity of type 'MyProject.DAL.User' 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.

    I want to map User to UserModel when I retrive it from database. I change UserModel properties in UI and then map it again to User and Update it. My code is here:

    public UserModel GetUserByUserId(int id)
        {
            var user = db.Users.Where(p => p.UserId == id).FirstOrDefault();
            var userModel = Mapper.Map<UserModel>(user);
            return userModel;
        }
    
    public void Update(UserModel userModel)
        {
            var user = Mapper.Map<User>(userModel);
            db.Entry(user).State = EntityState.Modified;
            db.SaveChanges();
        }
    

    but if I don't Use auto mapper and write something like below code, it work correctly.

    public void Update(UserModel userModel)
        {
            updatingUser.Email = userModel.Email;
            updatingUser.FirstName = userModel.FirstName;
            updatingUser.ModifiedDate = DateTime.Now;
            updatingUser.LastName = userModel.LastName;
            updatingUser.Password = userModel.Password;
            updatingUser.UserName = userModel.UserName;
    
            db.Entry(updatingUser).State = EntityState.Modified;
            db.SaveChanges();
        }
    

    What should I do:

  • overslacked
    overslacked over 8 years
    Exactly. EF needs to have a queried-from-the-database entity to update - not a newly constructed entity.
  • Ali Baig
    Ali Baig over 7 years
    @sam-i-am nicely explained but if UserModel has a collection of DTO, this map function tries to add that collection to the object we have retrieved from database (user in first example), which is incorrect. Is there a way around that?
  • Sam I am says Reinstate Monica
    Sam I am says Reinstate Monica over 7 years
    @AliBaig when configuring your mapping, you can set it up that it ignores that collection, and you merge the collection in manually