Entity Framework自增主键问题:插入UserMaster时主键重复报错
解决EF插入UserMaster时主键重复(值为0)的问题
问题根源
你碰到的这个错误核心原因很明确:你的UserID主键字段没有配置成自动递增(自增)。因为int类型的字段在EF中默认值是0,第一次插入时数据库接受了这个值(如果表是空的),但第二次插入时又用0作为UserID,直接触发了主键唯一约束,就报了重复键的错误。
解决方案
我们需要分两步操作:先修改数据库表结构让UserID自增,再配置EF实体让它识别这个自增主键。
1. 修改数据库表结构
如果表还没创建,直接用下面的建表语句(给UserID加上IDENTITY(1,1),表示从1开始每次自动加1):
CREATE TABLE [dbo].[UserMaster] ( [UserID] INT NOT NULL IDENTITY(1,1), [UserName] VARCHAR (50) NULL, [UserPassword] VARCHAR (50) NULL, [UserRoles] VARCHAR (500) NULL, [UserEmailID] VARCHAR (100) NULL, PRIMARY KEY CLUSTERED ([UserID] ASC) );
如果表已经存在,用ALTER语句修改UserID为自增字段(注意:如果表已有数据,要确保现有UserID没有冲突,或者先清空表):
ALTER TABLE [dbo].[UserMaster] ALTER COLUMN UserID INT IDENTITY(1,1);
2. 配置EF实体识别自增主键
有两种常用方式来告诉EF这个字段是数据库生成的自增主键:
方式一:使用数据注解(Attribute)
在你的UserMaster实体类中,给UserID属性加上对应的注解:
public class UserMaster { [Key] // 标记为主键 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] // 标记为数据库自动生成 public int UserID { get; set; } public string UserName { get; set; } public string UserPassword { get; set; } public string UserRoles { get; set; } public string UserEmailID { get; set; } }
方式二:使用Fluent API
在你的DbContext(也就是LessonesDBEntities)的OnModelCreating方法里添加配置:
public class LessonesDBEntities : DbContext { // ... 其他代码 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<UserMaster>() .HasKey(u => u.UserID) .Property(u => u.UserID) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); } }
3. 验证插入代码
你原来的插入代码不需要做任何修改,现在EF会自动跳过UserID的赋值,由数据库生成自增值,插入成功后u.UserID还会被自动填充为数据库生成的ID:
using (LessonesDBEntities context = new LessonesDBEntities()) { var u = new UserMaster { UserName = "test username", UserPassword = "test password", UserEmailID = "test email", UserRoles = "User" }; context.UserMaster.Add(u); context.SaveChanges(); // 这里可以输出u.UserID,会得到数据库生成的自增ID }
额外提醒
- 如果是Database First模式,修改完数据库后记得更新你的EDMX模型,确保实体配置和数据库同步;
- 如果是Code First模式,记得生成并执行迁移脚本,把结构变更同步到数据库。
内容的提问来源于stack exchange,提问作者Plompy
相关产品推荐
相关产品推荐

