为什么 Entity Framework 在我尝试关联现有实体时会创建一个新实体?

Why does Entity Framework create a new entity when I try to associate an existing one?

我有一个多对多关系(用户到技能),当我尝试将现有技能与用户相关联时,它总是会创建一个新技能。

用户:

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }

    public virtual ICollection<Skill> Skills { get; set; }
}

技能:

public class Skill
{
    public int Id { get; set; }

    public string Name { get; set; }
}

创建模型时:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<ApplicationUser>()
            .HasMany<Skill>(user => user.Skills)
            .WithMany();
    }

正在创建协会:

public ActionResult Skills(SkillsViewModel viewModel)
    {
        var user = UserManager.FindById(User.Identity.GetUserId());

        if(!string.IsNullOrWhiteSpace(viewModel.NewSkill)
            && !user.Skills
            .Where(sk => sk.Name == viewModel.NewSkill)
            .Any())
        {
            var foundSkill = this.db.Skills
                .Where(sk => sk.Name == viewModel.NewSkill)
                .FirstOrDefault();

            if(foundSkill != null)
            {
                user.Skills.Add(foundSkill);
            }
            else
            {
                user.Skills.Add(new Skill()
                    {
                        Name = viewModel.NewSkill
                    });
            }
        }

        if(viewModel.SelectedSkillId > 0)
        {
            var foundSkill = this.db.Skills.Find(viewModel.SelectedSkillId);


            user.Skills.Add(foundSkill);
        }

        this.UserManager.Update(user);

        return RedirectToAction("skills");
    }

我已经通过并验证了我确实从数据库中得到了 'foundSkill',但是在我将其添加到用户并保存用户之后,与用户关联的技能不是我找到的那个,但是一个同名不同 ID 的新的。

我明白了。 UserManager 正在加载一个 DbContext,而我试图关联从另一个 DbContext 加载的技能。

快速测试和修复此问题是从与技能相同的 DbContext 加载用户,更新用户,保存 DbContext。

长期解决方案是确保每个请求都使用相同的 DbContext。