Почему моя реализация вызова переноса базы данных ASPNET Core 2.1 на самом деле не применяет миграции? - PullRequest
0 голосов
/ 25 октября 2018

Я использую специализированную библиотеку .Net Core 2.1 для обработки миграций EF Core.Все это хорошо работает с Cli.Теперь я хочу, чтобы мой ASPNET Core 2.1 WebApi автоматически переносился при запуске.Мой WebApi ссылается на мою библиотеку миграции.

Вот интерфейс и его реализация, которые я объявляю в моей библиотеке миграции.

public class Migrator : IMigrator
{
    private readonly DbContextOptions _options;

    public Migrator(DbContextOptions options) => _options = options;

    public void Migrate()
    {
        using (var context = new MyContext(_options))
            context.Database.Migrate();
    }
}

public interface IMigrator
{
    void Migrate();
}

Вот мой WebApi Program.cs (вдохновленный этим repo )

public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateWebHostBuilder(args).Build();
        using (var scope = host.Services.CreateScope())
        {
            try
            {
                scope.ServiceProvider.GetService<IMigrator>().Migrate();
            }
            catch (Exception ex)
            {
                var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred while migrating the database.");
            }
        }
        host.Run();
    }

    private static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

А вот в моем startup.cs

services.AddScoped<IMigrator, Migrator>(_ => new Migrator(new DbContextOptionsBuilder<DbContext>()
            .UseSqlServer(Configuration.GetConnectionString("Write"))
            .Options));

Все сборки и запуска без исключений не ловятся.Однако мой последний перенос не применяется к базе данных.

ОБНОВЛЕНИЕ:

Принятый ответ привел меня к:

services.AddScoped<IMigrator, Migrator>(_ => new Migrator(Configuration.GetConnectionString("Write")));

и

public class Migrator : IMigrator
{
    private readonly string _connectionString;

    public Migrator(string connectionString) => _connectionString = connectionString;

    public void Migrate()
    {
        using (var context = GetContext(_connectionString))
            context.Database.Migrate();
    }

    private static MyContext GetContext(string connectionString)
    {
        var builder = new DbContextOptionsBuilder<GtaXContext>();
        builder.UseSqlServer(connectionString, b => b.MigrationsAssembly("MyApp.Context.Migrations"));
        return new MyContext (builder.Options);
    }
}

1 Ответ

0 голосов
/ 25 октября 2018

По умолчанию EF Core migrator предполагает, что сборка, содержащая миграции, - это та, которая содержит цель DbContext (typeof(MyContext).Assembly), которая, по-видимому, не применима в вашем случае.

Так что вам нужночтобы указать его явно с помощью метода MigrationsAssembly :

Конфигурирует сборку, в которой для этого контекста поддерживаются миграции.

Например:

.UseSqlServer(Configuration.GetConnectionString("Write"), options => options
    .MigrationAssembly(typeof(Migrator).Assembly.FullName))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...