问题描述
我有一个包含两个 DbContext 的控制台应用程序。一个是使用 Masstransit 配置的,另一个是对我已经运行迁移的另一个项目的引用。因此,我想在此服务上为 Masstransit 配置的 DbContext 运行迁移,但收到以下错误消息:
“找到了多个 DbContext。指定使用哪一个。对 PowerShell 命令使用“-Context”参数,对 dotnet 命令使用“--context”参数。”
但是,当我使用“dotnet ef migrations add InitialCreate -c CourierServiceDbContext”指定上下文时,出现以下错误:
“无法创建类型为“CourierServiceDbContext”的对象。有关设计时支持的不同模式,请参阅StatusOptions
明确地说,我只想为 Masstransit 配置的 DbContext、CourierServiceDbContext 而不是引用的 DbContext、OrdersDbContext 运行迁移。
static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder()
.UseSerilog((host,log) =>
{
string? appBin = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
log.MinimumLevel.information();
log.Writeto.File($"{appBin}/log/log-{DateTime.Now:yyMMdd_HHmmss}.txt");
log.Writeto.Console(LogEventLevel.Debug);
})
.ConfigureAppConfiguration((host,builder) =>
{
builder.AddJsonFile("appsettings.json",false);
})
.ConfigureServices((host,services) =>
{
services.AddDbContext<OrdersDbContext>(x =>
x.UseNpgsql(host.Configuration.GetConnectionString("OrdersConnection")));
services.AddMasstransit(x =>
{
x.AddConsumer<CourierdispatchConsumer>();
x.SetKebabCaseEndpointNameFormatter();
x.UsingRabbitMq((context,cfg) =>
{
string vhost = host.Configuration
.GetSection("Application")
.GetValue<string>("VirtualHost");
cfg.Host("localhost",vhost,h =>
{
h.Username("guest");
h.Password("guest");
});
cfg.ConfigureEndpoints(context);
// cfg.UseMessageRetry(x => x.SetRetryPolicy(new RetryPolicyFactory()));
});
x.AddSagaStateMachine<CourierStateMachine,CourierState>()
.EntityFrameworkRepository(r =>
{
r.ConcurrencyMode = ConcurrencyMode.Optimistic;
r.AddDbContext<DbContext,CourierServiceDbContext>((provider,builder) =>
{
builder.UseNpgsql(host.Configuration.GetConnectionString("OrdersConnection"),m =>
{
m.MigrationsAssembly(Assembly.GetExecutingAssembly().GetName().Name);
m.MigrationsHistoryTable($"__{nameof(CourierServiceDbContext)}");
});
});
});
});
services.AddMasstransitHostedService();
});
解决方法
通过调试各种错误,我发现了一些必须做的事情:
- 向两个 DbContext 添加一个构造函数,它接受 DbContextOptions 而不是只有 DbContextOptions
- 使用上下文切换执行迁移创建,如“dotnet ef migrations add InitialCreate -c
” - 使用上下文切换执行数据库同步命令,如“botnet ef database update -c
”
此外,您依赖 DbContext 的类应该注册为作用域,否则上述步骤将不起作用。
这将允许您在同一服务中注册多个 DbContext。