EF使用InMemory数据库测试时提示User实体需定义主键
EF Core InMemory测试报实体未定义主键的排查方案
优先排查版本一致性问题
90%的连接真实数据库正常,InMemory测试报主键缺失问题,都是EF Core相关包版本不匹配导致的。
请确保主项目、测试项目中所有EF Core关联包的版本号完全一致(包括小补丁版本,不允许出现版本差),需要对齐版本的包包括:
Microsoft.EntityFrameworkCoreMicrosoft.EntityFrameworkCore.InMemory- 生产环境使用的数据库EF Core提供程序(如
Microsoft.EntityFrameworkCore.SqlServer)
版本不匹配时,不同程序集的模型构建逻辑存在差异,会导致[Key]这类数据注解识别失效;生产环境因为数据库提供程序和主项目EF Core版本匹配,所以不会出现该问题。
修复InMemory模型缓存冲突
EF Core InMemory提供商会根据上下文类型、数据库名缓存模型构建结果,如果你之前跑过同名InMemory库的测试,残留的错误缓存会导致当前测试加载错误模型。
修改测试构造函数中的数据库名配置,每次测试生成唯一的库名,彻底规避缓存冲突:
var dbContextOptions = new DbContextOptionsBuilder<UserDbContext>() // 用Guid生成唯一库名,每次测试使用全新实例,不残留旧缓存 .UseInMemoryDatabase(Guid.NewGuid().ToString()) .ConfigureWarnings(b => b.Ignore(InMemoryEventId.TransactionIgnoredWarning)) .Options;
显式用FluentAPI配置主键(兜底方案)
如果前两步操作后还是报错,直接在OnModelCreating中用FluentAPI显式配置主键,该方式优先级高于数据注解,不会出现识别偏差:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 显式指定User实体主键 modelBuilder.Entity<User>().HasKey(u => u.Id); base.OnModelCreating(modelBuilder); }
同时需要确认你代码中[Key]特性引用的是System.ComponentModel.DataAnnotations命名空间下的官方特性,而非项目自定义的同名特性、或老版EF6的同名特性。
排查其他实体配置问题
EF Core构建模型时会扫描所有注册到UserDbContext的实体,包括你代码中定义的Currency、Country、Upload、UploadObject。如果这些实体存在主键缺失问题,部分版本的InMemory提供程序抛出异常时会错误标注实体名为User。可以临时注释其他实体的DbSet配置,仅保留DbSet<User>后运行测试,确认异常是否由其他实体配置错误导致。
以上操作完成后,无需编写任何测试用例,测试类构造函数即可正常执行,不会再抛出主键缺失异常。
内容的提问来源于stack exchange,提问作者Nahuel
相关产品推荐
相关产品推荐

