EF Core内存数据库专为单元测试设计,轻量快速且隔离,但不支持复杂SQL、事务回滚、外键约束等,适合验证业务逻辑;需手动初始化数据,避免测试污染。
EF Core内存数据库(InMemory Provider)不是用来跑生产环境的,它是专为快速、隔离的单元测试设计的轻量级模拟工具。用它,你不用装SQL Server、不用连网络、不依赖Docker容器,几毫秒就能启动一个干净的“假数据库”。
先装NuGet包:
dotnet add package Microsoft.EntityFrameworkCore.InMemory然后在测试代码里配置DbContext选项:
var options = new DbContextOptionsBuilder()
.UseInMemoryDatabase(databaseName: "TestDb_" + Guid.NewGuid()) // 推荐用唯一名
.Options;
每次用不同databaseName,就得到一个完全独立的内存数据库实例——避免测试间数据污染。
内存数据库不自动建表,也不执行迁移,所以你得靠代码“手动初始化”数据:
context.AddRange() + context.SaveChanges() 插入测试数据SeedData(context)方法,在每个测试前调用EnsureCreated(),它对InMemory无效;也不要调Migrate(),它不支持迁移示例:
using var context = new AppDbContext(options);
context.Users.AddRange(
new User { Id = 1, Name = "Alice" },
new User { Id = 2, Name = "Bob" });
context.SaveChanges();
var found = context.Users.FirstOrDefault(u => u.Name == "Alice");
Assert.NotNull(found);
它快,但不等于“真实数据库”。以下情况容易踩坑:
public DateTime CreatedAt { get; set; }会变成0001-01-01,需手动赋值或配HasValueGenerator()
SaveChanges()后数据就“真存了”,只能靠context.Database.
EnsureDeleted()清空整个库如果你的测试需要验证:
ORDER BY加LIMIT)那就改用Microsoft.EntityFrameworkCore.Sqlite配合DataSource=:memory:——它更接近真实数据库,只是仍运行在进程内。
基本上就这些。用对场景,它就是单元测试的加速器;硬套在不该用的地方,反而掩盖真实问题。