Создание DbContext во время разработки

Некоторые команды EF Core Tools (например, команды миграции ) требуют создания производного DbContext экземпляра во время разработки для сбора сведений о типах сущностей приложения и их сопоставлении с схемой базы данных. В большинстве случаев рекомендуется DbContext настроить таким образом, чтобы он был настроен во время выполнения.

Существуют различные способы создания DbContextследующих средств:

Из служб приложений

Если в проекте запуска используется веб-узел ASP.NET Core или универсальный узел .NET Core, средства пытаются получить объект DbContext от поставщика услуг приложения.

Средства сначала пытаются получить поставщика услуг путем вызова, вызоваProgram.CreateHostBuilder()Build(), а затем доступа к свойствуServices.

public class Program
{
    public static void Main(string[] args)
        => CreateHostBuilder(args).Build().Run();

    // EF Core uses this method at design time to access the DbContext
    public static IHostBuilder CreateHostBuilder(string[] args)
        => Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(
                webBuilder => webBuilder.UseStartup<Startup>());
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
        => services.AddDbContext<ApplicationDbContext>();

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    }
}

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

Примечание.

При создании нового приложения ASP.NET Core этот перехватчик включается по умолчанию.

Само DbContext и все зависимости в конструкторе должны быть зарегистрированы в качестве служб в поставщике услуг приложения. Это можно легко достичь, имея конструктор на объектеDbContext, который принимает экземпляр в качестве аргументаDbContextOptions<TContext> и используя AddDbContext<TContext> метод.

Использование конструктора без параметров

Если dbContext не удается получить от поставщика службы приложений, средства ищут производный DbContext тип внутри проекта. Затем они пытаются создать экземпляр с помощью конструктора без параметров. Это может быть конструктор по умолчанию, если DbContext он настроен с помощью OnConfiguring метода.

Из фабрики времени разработки

Вы также можете рассказать инструментам, как создать DbContext, реализуя Microsoft.EntityFrameworkCore.Design.IDesignTimeDbContextFactory<TContext> интерфейс: если класс, реализующий этот интерфейс, найден в том же проекте, что и производный DbContext или в проекте запуска приложения, средства обходя другие способы создания DbContext и использовать фабрику времени разработки.

public class BloggingContextFactory : IDesignTimeDbContextFactory<BloggingContext>
{
    public BloggingContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
        optionsBuilder.UseSqlite("Data Source=blog.db");

        return new BloggingContext(optionsBuilder.Options);
    }
}

Фабрика времени разработки может быть особенно полезной, если необходимо настроить DbContext время разработки по-разному, чем во время выполнения, если конструктор принимает дополнительные параметры, не зарегистрированы в di, если DbContext вы не используете di вообще, или если по какой-то причине вы предпочитаете не иметь CreateHostBuilder метод в классе приложения ASP.NET Core Main .

Args

Оба IDesignTimeDbContextFactory<TContext>.CreateDbContext и Program.CreateHostBuilder примите аргументы командной строки.

Эти аргументы можно указать из средств:

dotnet ef database update -- --environment Production

Маркер -- направляет dotnet ef для обработки всего следующего как аргумента и не пытается проанализировать их как параметры. Все дополнительные аргументы, не используемые dotnet ef приложением, перенаправляются в приложение.