'entity of the same type already has the same

2019-05-13 15:46发布

问题:

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:

回答1:

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();
}


回答2:

object A and his child object B and then setting all properties from and then flushing it towards the . We no longer: attached the (Object A and B from previous ) We no longer fetched object B separately.