执行Add-Migration和Update-Database时出现重复键错误求助
解决EF Core执行迁移时"An item with the same key has already been added"错误
错误原因
你遇到的错误是因为ForeignKey属性的使用方式错误:
你将[ForeignKey("ProductId")]标记在了ProductId字段上,这会让EF Core误以为这个字段是对应名为"ProductId"的导航属性的外键,但实际上ProductId本身就是外键字段,对应的导航属性是Product。这种错误标记导致EF Core重复注册外键关联,从而抛出重复键异常。
同样的问题也出现在ApplicationUserId和ApplicationUser的关联上。
解决方案
下面提供几种可行的修正方式:
方式1:修正ForeignKey属性的参数(外键字段标记)
将外键字段上的ForeignKey属性参数改为导航属性的名称:
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations; namespace Bulky.Models1 { public class NewShoppingCart { public int Id { get; set; } [ForeignKey("Product")] // 参数改为导航属性名称"Product" [ValidateNever] public int ProductId { get; set; } public Product Product { get; set; } [Range(1, 1000, ErrorMessage = "Please enter a value between 1 to 1000")] public int Count { get; set; } [ForeignKey("ApplicationUser")] // 参数改为导航属性名称"ApplicationUser" [ValidateNever] public string ApplicationUserId { get; set; } public ApplicationUser ApplicationUser { get; set; } } }
方式2:将ForeignKey属性移到导航属性上
把ForeignKey属性标记在对应的导航属性上,参数为外键字段的名称:
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations; namespace Bulky.Models1 { public class NewShoppingCart { public int Id { get; set; } [ValidateNever] public int ProductId { get; set; } [ForeignKey("ProductId")] // 标记在导航属性上,参数为外键字段名 public Product Product { get; set; } [Range(1, 1000, ErrorMessage = "Please enter a value between 1 to 1000")] public int Count { get; set; } [ValidateNever] public string ApplicationUserId { get; set; } [ForeignKey("ApplicationUserId")] // 标记在导航属性上,参数为外键字段名 public ApplicationUser ApplicationUser { get; set; } } }
方式3:利用EF Core约定自动识别(最简洁)
如果你遵循EF Core的命名约定(外键字段名=导航属性名+Id),可以完全去掉ForeignKey属性,EF Core会自动关联外键和导航属性:
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using System.ComponentModel.DataAnnotations; namespace Bulky.Models1 { public class NewShoppingCart { public int Id { get; set; } [ValidateNever] public int ProductId { get; set; } public Product Product { get; set; } [Range(1, 1000, ErrorMessage = "Please enter a value between 1 to 1000")] public int Count { get; set; } [ValidateNever] public string ApplicationUserId { get; set; } public ApplicationUser ApplicationUser { get; set; } } }
后续操作
- 如果已经生成了错误的迁移文件,先删除该文件;
- 重新执行迁移命令:
Add-Migration AddNewShoppingCartTable - 执行更新数据库命令:
Update-Database
内容的提问来源于stack exchange,提问作者Durgesh Marrathe
相关产品推荐
相关产品推荐

