为什么EntityFramework未将AutoBogus生成的测试数据写入内存数据库?
EF Core 内存数据库插入AutoBogus生成数据失败解决方案
核心问题原因
- 多个上下文实例未共享服务提供器,相同数据库名也会指向独立的内存存储空间
- Goal实体主键默认配置为自增,EF Core自动忽略手动设置的Id值,导致插入失败
- 后续查询使用的上下文配置与初始化数据的上下文配置不一致,访问到空数据库
修复步骤
1. 配置共享服务提供器,确保多上下文访问同一内存库
// 全局共享服务提供器,所有上下文实例都要使用该配置 var serviceProvider = new ServiceCollection() .AddEntityFrameworkInMemoryDatabase() .BuildServiceProvider(); // 生成测试数据 var goalFaker = new AutoFaker<Goal>() .RuleFor(g => g.Id, f => f.IndexFaker + 1); var goals = goalFaker.Generate(10); // 上下文配置必须绑定共享服务提供器 var options = new DbContextOptionsBuilder<GoalContext>() .UseInMemoryDatabase(databaseName: "TestDatabase") .UseInternalServiceProvider(serviceProvider) .Options; // 插入数据 using (var context = new GoalContext(options)) { context.AddRange(goals); // 可通过返回值验证插入行数,正常应为10 var count = context.SaveChanges(); }
2. 禁用主键自动生成策略
两种方式二选一即可:
方式A:数据注解方式
在Goal实体类的Id属性上添加注解:
public class Goal { [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } // 其他属性 }
方式B:FluentAPI配置
在GoalContext的OnModelCreating方法中添加配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Goal>() .Property(p => p.Id) .ValueGeneratedNever(); }
3. 后续查询上下文配置保持一致
所有需要访问该测试数据库的上下文,都必须使用上述相同的options实例初始化,不能重新构建不带共享服务提供器的配置:
// 正确示例 using (var queryContext = new GoalContext(options)) { var allGoals = queryContext.Goals.ToList(); // 此时可正常查询到10条测试数据 }
内容的提问来源于stack exchange,提问作者ricksmt
相关产品推荐
相关产品推荐

