EF Core执行数据种子迁移报IdentityUserLogin<string>需主键错误
报错根因
- 重写
OnModelCreating时没有调用基类IdentityDbContext.OnModelCreating()方法。Identity框架内置的IdentityUserLogin、IdentityUserRole等所有认证相关实体的主键、表映射规则都在基类方法里配置,直接覆盖方法逻辑不调用基类实现,会导致这些实体缺失主键配置,触发校验异常。 - 错误给
Animal实体配置了HasNoKey()。无键实体类型仅用于只读查询、数据库视图映射场景,不支持增删改操作,也不支持HasData种子数据迁移,而Animal实体明确存在AnimalId字段作为业务主键,不需要配置无键。 - 种子数据里的日期字符串末尾多了多余逗号(比如
"2022-08-01,"),就算解决前两个问题,运行时也会抛出日期格式解析错误。
修复步骤
- 修改
AnimalShelterContext的OnModelCreating方法:- 方法第一行先调用
base.OnModelCreating(modelBuilder),加载Identity框架的默认实体配置 - 移除
Animal实体的HasNoKey()配置,显式指定AnimalId为主键(如果AnimalId字段已经加了[Key]数据标注,这步可省略) - 删掉所有
DateTime.Parse入参末尾多余的逗号
- 方法第一行先调用
- 删除之前生成的错误迁移文件:如果之前生成过失败的迁移,直接删掉Migrations文件夹下对应批次的文件即可,全量重置可以直接删除整个Migrations文件夹
- 重新执行迁移生成命令:
dotnet ef migrations add "data seed" - 待迁移生成无报错后,执行
dotnet ef database update将表结构和种子数据应用到数据库
修正后的完整上下文代码
using System; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; namespace AnimalShelter.Models { public class AnimalShelterContext : IdentityDbContext { public AnimalShelterContext(DbContextOptions<AnimalShelterContext> options) : base(options) { } public DbSet<Animal> Animals { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 必须首先调用基类方法完成Identity实体配置 base.OnModelCreating(modelBuilder); modelBuilder.Entity<Animal>() .HasKey(a => a.AnimalId) .HasData( new Animal { AnimalId = 6, Name = "Matilda", Neutered = "Y", Age = 7, Species = "Dog", Gender = "Female", DateAdd = DateTime.Parse("2022-08-01")}, new Animal { AnimalId = 2, Name = "Rexie", Neutered = "Y", Age = 10, Species = "Dog", Gender = "Female", DateAdd = DateTime.Parse("2022-02-01")}, new Animal { AnimalId = 3, Name = "Matilda", Neutered = "N", Age = 2, Species = "Cat", Gender = "Female", DateAdd = DateTime.Parse("2022-03-01")}, new Animal { AnimalId = 4, Name = "Pip", Neutered = "Y", Age = 4, Species = "Bird", Gender = "Male", DateAdd = DateTime.Parse("2022-07-01")}, new Animal { AnimalId = 5, Name = "Bartholomew", Neutered = "N", Age = 22, Species = "Cat", Gender = "Male", DateAdd = DateTime.Parse("2022-06-01")} ); } } }
补充说明:只要继承了Identity相关的上下文类,重写
OnModelCreating时都需要首先调用基类方法,否则Identity内置的所有实体配置都会丢失。
内容的提问来源于stack exchange,提问作者NWclimber
相关产品推荐
相关产品推荐

