ASP.NET Core创建用户报错:同一主键实体被重复跟踪
问题排查与解决方案
问题原因
核心冲突来自User实体的导航属性自动初始化:
- 在User类中,
public UserDetails UserDetails { get; set; } = new UserDetails();这行代码会在创建User实例时,自动生成一个空的UserDetails对象。当你执行_context.WMS_User.Add(user)时,EF Core会自动跟踪这个关联的空UserDetails实例,并且会将它的UserID关联为当前User的UserID。 - 之后你手动创建了一个新的UserDetails实例并设置了相同的UserID,再执行
_context.WMS_UserDetails.Add(userDetails)时,EF Core发现上下文已经在跟踪一个拥有相同主键(UserID)的UserDetails实例,因此抛出System.InvalidOperationException。
解决方案
方案1:移除导航属性的默认初始化
修改User类中的导航属性,取消自动初始化空实例:
public class User { public string UserID { get; set; } public string Password { get; set; } public string Role { get; set; } public string Status { get; set; } public DateTime CreatedDate { get; set; } public string ModifiedBy { get; set; } public DateTime ModifiedDate { get; set; } // 移除默认的=new UserDetails()初始化 public UserDetails UserDetails { get; set; } public ICollection<UserContact> Contacts { get; set; } = new List<UserContact>(); }
修改后,EF Core不会自动跟踪空的UserDetails实例,你可以正常执行_context.WMS_UserDetails.Add(userDetails)插入数据。
方案2:关联手动创建的UserDetails到User实例
保留导航属性的默认初始化,但不要单独调用Add方法,而是将手动创建的userDetails赋值给User的导航属性:
// 替换原来的_context.WMS_UserDetails.Add(userDetails); user.UserDetails = userDetails;
这样EF Core会自动处理关联跟踪,执行SaveChangesAsync时会同时插入User和对应的UserDetails数据,无需单独添加UserDetails到上下文。
补充优化建议
在ApplicationDbContext的OnModelCreating中显式配置User和UserDetails的一对一关系,让EF Core更清晰识别关联规则:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<User>() .HasKey(r => r.UserID); modelBuilder.Entity<UserContact>() .HasKey(r => r.UserContactID); modelBuilder.Entity<User>() .HasMany(r => r.Contacts) .WithOne(a => a.User) .HasForeignKey(a => a.UserID); // 添加一对一关系配置 modelBuilder.Entity<User>() .HasOne(u => u.UserDetails) .WithOne(ud => ud.User) .HasForeignKey<UserDetails>(ud => ud.UserID); }
内容的提问来源于stack exchange,提问作者Erck
相关产品推荐
相关产品推荐

