EF Core 3.1在添加新实体时重新插入现有的导航属性



我正在向DbContext添加一个带有从客户端传递的导航属性的新实体,但不是EF识别导航属性实体已经存在,而是尝试重新插入它,因为你不能有重复的主键。

var profile = _mapper.Map<Profile>(profileDto);
profile.User.LockoutEnabled = true;
profile.User.Password = new PasswordHasher<User>().HashPassword(profile.User, "*********");
profile.Company = null; // Doing this works fine but otherwise it fails.
await _dataContext.Set<Profile>().AddAsync(profile);
await _dataContext.SaveChangesAsync();

profile.Company = await _dataContext.Set<Company>().FindAsync(profile.CompanyId);
return _mapper.Map<ProfileCreateDto>(profile);

由于取消Company实体或更改客户端以仅传递CompanyId而不是Company值可以正常工作,我仍然想理解为什么EF试图重新插入现有实体。

EF正在尝试重新插入Company实体,因为您正在使用AddAsync方法插入Profile实体。

AddAsync方法导致存在问题的实体(Profile)及其在实体图中的所有相关实体(例如Company)被标记为Added。标记为Added的实体意味着-This is a new entity and it will get inserted on the next SaveChanges call.参见详细信息-DbSet<TEntity>.AddAsync()

作为一般解决方案,在断开连接的场景中,当使用实体图创建新实体(具有一个或多个相关实体)时,使用Attach方法代替。

Attach方法使任何实体只有在没有设置主键值时才被标记为Added。否则,该实体被标记为Unchanged。标记为Unchanged的实体意味着-This entity already exists in the database and it might get updated on the next SaveChanges call.参见详细信息-DbSet<TEntity>.Attach()

我希望这能满足你的好奇心。

最新更新