ASP.NET Core中EF Core保存数据时主键重复错误求助
问题原因分析
错误提示明确显示主键约束冲突,重复键值为0,核心问题出在BankAccount实体的主键配置和页面数据提交逻辑上:
你的BankAccount实体中,BankAccountID被标记为[DatabaseGenerated(DatabaseGeneratedOption.None)],这意味着EF Core不会让数据库自动生成主键值,必须由你手动提供唯一的ID。
通过页面新增第四条数据时,提交的BankAccount对象的BankAccountID值为默认的0,而数据库中已存在主键为0的记录(前三条录入时可能手动传入了合法ID,第四条未传入导致使用默认值);而通过SSMS手动录入时,你主动指定了唯一的主键ID,因此不会触发错误。
解决方案
根据需求,有两种可行处理方式:
方式一:让数据库自动生成主键(推荐)
如果无需手动控制主键,修改BankAccount实体的主键配置,移除手动指定的生成规则,让EF Core默认将int类型主键设为自增:
using System.ComponentModel.DataAnnotations.Schema; namespace ContosoUniversity.Models { public class BankAccount { public int BankAccountID { get; set; } public int Credits { get; set; } public ICollection<BankAccountMember> BankAccountMembers { get; set; } } }
修改后需执行数据库迁移,确保数据库表的主键列设置为自增(Identity)。
方式二:手动指定主键值
如果必须手动控制主键ID,需在页面中添加BankAccountID的输入字段,确保提交时提供唯一ID:
- 在Create.cshtml页面中添加输入框:
<div class="form-group"> <label asp-for="BankAccount.BankAccountID" class="control-label"></label> <input asp-for="BankAccount.BankAccountID" class="form-control" /> <span asp-validation-for="BankAccount.BankAccountID" class="text-danger"></span> </div>
- 可选:在
OnPostAsync中提前验证ID唯一性,避免数据库报错:
public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return Page(); } var existingAccount = await _context.bankAccounts.FirstOrDefaultAsync(a => a.BankAccountID == BankAccount.BankAccountID); if (existingAccount != null) { ModelState.AddModelError("BankAccount.BankAccountID", "该账户ID已存在"); return Page(); } _context.bankAccounts.Add(BankAccount); await _context.SaveChangesAsync(); return RedirectToPage("./Index"); }
额外排查点
- 检查前三条页面录入数据的
BankAccountID值,确认是否存在值为0的记录,这会导致后续默认值提交时冲突。 - 确认页面表单中
BankAccountID字段已正确渲染,避免因未提交该字段而使用默认值0。
内容的提问来源于stack exchange,提问作者Abozar Nazari Zohan
相关产品推荐
相关产品推荐

