使用AutoMapper时出现“相同类型的实体已经具有相同的主键值”错误

3
当我使用AutoMapper时,出现了以下错误:
“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.”
我想要在从数据库中检索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();
    }

但是如果我不使用自动映射器,而是像下面的代码一样编写,它可以正常工作。
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();
    }

我该怎么做:


5
“updatingUser” 在你的第二个更新函数中似乎突然出现了。 - Sam I am says Reinstate Monica
2个回答

15

这可能只是因为我不知道某些功能,但是你的 update 函数看起来对我来说有点奇怪。我不知道它如何将新的user与数据库中的现有用户关联起来。

我会这样处理。

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

或者,如果您喜欢像第二个update函数一样执行它

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

4
没错。EF需要从数据库中查询到实体才能进行更新,而不是使用新构建的实体进行更新。 - overslacked
@sam-i-am 解释得很好,但是如果 UserModel 有一个 DTO 集合,那么这个 map 函数尝试将该集合添加到我们从数据库中检索的对象中(第一个示例中的 user),这是不正确的。有没有什么方法可以解决这个问题? - Ali Baig
@AliBaig 在配置映射时,你可以设置忽略该集合,并手动合并该集合。 - Sam I am says Reinstate Monica

-6

对象A及其子对象B,然后从中设置所有属性,并将其刷新到目标处。 我们不再:附加先前的(对象A和B)。 我们不再单独获取对象B。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接