У меня есть консольное приложение с двумя DbContexts. Один настроен с помощью MassTransit, а другой является ссылкой на другой проект, для которого я уже выполняю миграции. Итак, я хочу запустить миграцию в этой службе для DbContext, настроенного MassTransit, и получаю следующее сообщение об ошибке:
«Найдено несколько DbContext. Укажите, какой из них использовать. Используйте параметр «-Context» для команд PowerShell и параметр «--context» для команд dotnet».
Однако, когда я указываю контекст с помощью «миграции dotnet ef add InitialCreate -c CourierServiceDbContext», я получаю следующую ошибку:
«Невозможно создать объект типа CourierServiceDbContext». Чтобы узнать о различных шаблонах, поддерживаемых во время разработки, см. https://go.microsoft.com/fwlink/?linkid=851728"
Чтобы было ясно, я хочу запускать миграции только для DbContext, CourierServiceDbContext, настроенного для MassTransit, а не для упомянутого 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();
});
Не думайте, что это связано. Я думаю, разница в том, что у меня есть 2 проекта, P1 и P2. P1 имеет DbContext, для которого я могу успешно выполнить миграцию ef. Однако в P2 у меня есть конечные автоматы, для которых мне нужно выполнить миграцию, но у меня также есть потребители, которые ссылаются на DbContext в P1, поэтому мне нужно зарегистрировать оба DbContext в HostBuilder.
Комментирование регистрационного кода, который ссылается на DbContext P1, позволяет мне запускать миграции с помощью миграции dotnet ef add InitialCreate -c MyMassTransitDbContext.
Я нашел пару вещей, которые мне пришлось сделать, отладив различные ошибки:
Кроме того, ваш класс, который зависит от DbContext, должен быть зарегистрирован как ограниченный, иначе описанные выше шаги не будут работать.
Это позволит вам зарегистрировать несколько DbContexts в одной и той же службе.