You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何采用数据库优先方式配置Testcontainers?

用Testcontainers实现SQL Server数据库优先的集成测试方案

问题说明

  • 要在集成测试中使用Testcontainers,但找不到数据库优先模式的配置方案,项目包含SQL Server的.sqlproj文件,不知如何配置容器数据库
  • 当前使用await context.Database.EnsureCreatedAsync();仅能创建表,无法生成视图(因该方法基于DbContext,不会处理.sqlproj中定义的视图等非实体类数据库对象)

可行解决方案

方案一:执行.sqlproj编译生成的完整数据库脚本

.sqlproj编译后会生成包含所有数据库对象(表、视图、存储过程等)的SQL脚本,可在Testcontainers初始化时执行该脚本:

  1. 配置.sqlproj生成创建脚本:右键项目→属性→生成→勾选「生成创建脚本」,指定输出路径
  2. 在测试初始化阶段读取脚本并执行

修改InitializeAsync方法如下:

public async Task InitializeAsync()
{
    await _container.StartAsync();

    var masterConnectionString = _container.GetConnectionString();
    var connectionStringBuilder = new SqlConnectionStringBuilder(masterConnectionString)
    {
        InitialCatalog = "master"
    };

    // 创建目标数据库
    using (var connection = new SqlConnection(connectionStringBuilder.ConnectionString))
    {
        await connection.OpenAsync();
        using (var command = new SqlCommand("CREATE DATABASE MyDatabase", connection))
        {
            await command.ExecuteNonQueryAsync();
        }
    }

    connectionStringBuilder.InitialCatalog = "MyDatabase";
    var targetConnectionString = connectionStringBuilder.ConnectionString;

    // 读取并执行.sqlproj生成的数据库创建脚本
    var scriptPath = Path.Combine(AppContext.BaseDirectory, "MyDatabaseCreationScript.sql");
    var sqlScript = await File.ReadAllTextAsync(scriptPath);

    using (var connection = new SqlConnection(targetConnectionString))
    {
        await connection.OpenAsync();
        using (var command = new SqlCommand(sqlScript, connection))
        {
            await command.ExecuteNonQueryAsync();
        }
    }

    // 配置服务并构建容器
    var serviceCollection = GetServices(targetConnectionString);
    ServiceProvider = serviceCollection.BuildServiceProvider();
}

方案二:基于EF Core迁移适配测试容器

若偏好使用EF Core的迁移机制,可从现有数据库(基于.sqlproj)生成迁移,再在测试中执行迁移:

  1. 从数据库生成DbContext和实体类:
Scaffold-DbContext "Server=.;Database=MyDatabase;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDbContext
  1. 生成初始迁移文件:
Add-Migration InitialCreate
  1. 在测试中用MigrateAsync()替代EnsureCreatedAsync(),迁移会处理所有数据库对象:

修改初始化中的DbContext初始化代码:

using var scope = ServiceProvider.CreateScope();
var scopedServices = scope.ServiceProvider;
var context = scopedServices.GetRequiredService<MyDbContext>();

// 执行迁移创建所有数据库对象
await context.Database.MigrateAsync();

代码优化建议

  • GetServices方法中重复注册了MyDbContext,可移除冗余注册:
private IServiceCollection GetServices(string connectionString)
{
    var services = new ServiceCollection();

    services.AddTransient<IMyServices, MyServices>();
    services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connectionString));

    return services;
}

内容的提问来源于stack exchange,提问作者ChinnMan Spam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 19:13:14