【发布时间】:2019-10-12 15:36:02
【问题描述】:
对于集成测试,我正在使用 EntityFrameworkCore SQLite 内存数据库并根据 Microsoft 文档创建其架构,但是当我尝试播种数据时会引发异常,即表不存在。
DbContext.Database.EnsureCreated(); 的鼠标悬停文档:
确保上下文的数据库存在。如果存在,没有 采取行动。如果它不存在,那么数据库及其所有 架构被创建。如果数据库存在,则不执行任何操作 确保它与此上下文的模型兼容。
我读过EntityFrameworkCore 内存数据库仅在打开连接存在时才存在,因此我尝试显式创建var connection = new SqliteConnection("DataSource=:memory:"); 实例并将以下代码包装在using(connection) {} 块中并传递连接实例options.UseSqlite(connection);,但DbContext.Database.EnsureCreated(); 仍然没有创建任何数据库对象
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<Startup>
{
protected override IWebHostBuilder CreateWebHostBuilder()
{
return WebHost.CreateDefaultBuilder()
.UseStartup<Startup>();
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
using (var connection = new SqliteConnection("DataSource=MySharedInMemoryDb;mode=memory;cache=shared"))
{
connection.Open();
builder.ConfigureServices(services =>
{
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkSqlite()
.BuildServiceProvider();
services.AddDbContext<MyDbContext>(options =>
{
options.UseSqlite(connection);
options.UseInternalServiceProvider(serviceProvider);
});
var contextServiceProvider = services.BuildServiceProvider();
// we need a scope to obtain a reference to the database contexts
using (var scope = contextServiceProvider.CreateScope())
{
var scopedProvider = scope.ServiceProvider;
var logger = scopedProvider.GetRequiredService<ILogger<CustomWebApplicationFactory<TStartup>>>();
using (var myDb = scopedProvider.GetRequiredService<MyDbContext>())
{
// DEBUG CODE
// this returns script to create db objects as expected
// proving that MyDbContext is setup correctly
var script = myDb.Database.GenerateCreateScript();
// DEBUG CODE
// this does not create the db objects ( tables etc )
// this is not as expected and contrary to ms docs
var result = myDb.Database.EnsureCreated();
try
{
SeedData.PopulateTestData(myDb);
}
catch (Exception e)
{
// exception is thrown that tables don't exist
logger.LogError(e, $"SeedData.PopulateTestData(myDb) threw exception=[{e.Message}]");
}
}
}
});
}
builder.UseContentRoot(".");
base.ConfigureWebHost(builder);
}
请注意,在这篇文章中,我只是在问为什么DbContext.Database.EnsureCreated(); 没有按预期创建架构。我没有将上述代码作为运行集成测试的一般模式。
【问题讨论】:
-
什么是
chatDb?应该是MyDb? -
糟糕,现在已修复。
-
EF Core 内存数据库(与 SQLite 内存数据库相反)没有您描述的行为。你能指出我在哪里找到这个文件以便我修复它吗?谢谢。
标签: c# sqlite integration-testing in-memory-database entity-framework-core-2.2