使用AutoMapper,"相同类型的实体已经具有相同的主键值"错误

ali*_*ite 3 c# entity-framework automapper

当我使用AutoMapper时,出现此错误:

附加"MyProject.DAL.User"类型的实体失败,因为同一类型的另一个实体已具有相同的主键值.如果图中的任何实体具有冲突的键值,则在使用"附加"方法或将实体的状态设置为"未更改"或"已修改"时,可能会发生这种情况.这可能是因为某些实体是新的并且尚未收到数据库生成的键值.在这种情况下,使用"添加"方法或"已添加"实体状态来跟踪图形,然后根据需要将非新实体的状态设置为"未更改"或"已修改".

我想从数据库中检索User时将User映射到UserModel.我在UI中更改UserModel属性,然后再将其映射到User并更新它.我的代码在这里:

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();
    }
Run Code Online (Sandbox Code Playgroud)

但如果我不使用自动映射器并编写类似下面的代码,它可以正常工作.

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();
    }
Run Code Online (Sandbox Code Playgroud)

我该怎么办:

Sam*_*ica 15

这可能只是我不知道某些功能,但你的update功能看起来很时髦.我没有看到它如何将您的新内容user与数据库中的现有内容相关联.

这就是我接近它的方式.

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

或者,如果你喜欢像你的第二个update功能那样做

public void Update(UserModel userModel)
{
    Mapper.Map(userModel, updatingUser);
    db.Entry(updatingUser).State = EntityState.Modified;
    db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

  • 究竟.EF需要从数据库查询实体进行更新 - 而不是新构建的实体. (4认同)