DbContext-Instanzerstellung zur Entwurfszeit

Einige der EF Core Tools-Befehle (z. B. migrations-Befehle) DbContext erfordern, dass zur Entwurfszeit eine abgeleitete Instanz erstellt wird, um Details zu den Entitätstypen der Anwendung und deren Zuordnung zu einem Datenbankschema zu sammeln. In den meisten Fällen ist es DbContext wünschenswert, dass die dadurch erstellte auf ähnliche Weise wie zur Laufzeit konfiguriert wird.

Es gibt verschiedene Möglichkeiten, wie die Tools versuchen, das zu erstellen DbContext:

Aus Anwendungsdiensten

Wenn Ihr Startprojekt den ASP.NET Core Webhost oder den generischen .NET Core-Host verwendet, versuchen die Tools, das DbContext-Objekt vom Dienstanbieter der Anwendung zu erhalten.

Die Tools versuchen zunächst, den Dienstanbieter zu erhalten Program.CreateHostBuilder(), indem sie aufrufen, Build()aufrufen und dann auf die -Eigenschaft Services zugreifen.

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)
    {
    }
}

Hinweis

Wenn Sie eine neue ASP.NET Core erstellen, ist dieser Hook standardmäßig enthalten.

Der DbContext selbst und alle Abhängigkeiten in seinem Konstruktor müssen als Dienste im Dienstanbieter der Anwendung registriert werden. Dies kann problemlos erreicht werden, indem ein Konstruktor für den DbContext verwendet wird, der eine Instanz DbContextOptions<TContext> von als Argument verwendet und die -Methode AddDbContext<TContext> verwendet.

Verwenden eines Konstruktors ohne Parameter

Wenn dbContext nicht vom Anwendungsdienstanbieter erhalten werden kann, DbContext suchen die Tools im Projekt nach dem abgeleiteten Typ. Anschließend wird versucht, eine -Instanz mit einem Konstruktor ohne Parameter zu erstellen. Dies kann der Standardkonstruktor sein, wenn DbContext mit der -Methode konfiguriert OnConfiguring wird.

Aus einer Entwurfszeit-Factory

Sie können den Tools auch mitteilen, wie Ihr DbContext Microsoft.EntityFrameworkCore.Design.IDesignTimeDbContextFactory<TContext> erstellt werden soll, indem Sie die -Schnittstelle implementieren: Wenn eine Klasse, die diese Schnittstelle implementiert, entweder im DbContext selben Projekt wie das abgeleitete oder im Startprojekt der Anwendung gefunden wird, umgehen die Tools die anderen Methoden zum Erstellen des DbContext und verwenden stattdessen die Entwurfszeit-Factory.

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);
    }
}

Hinweis

Vor EFCore 5.0 wurde der args Parameter nicht verwendet (siehe dieses Problem). Dies ist in EFCore 5.0 behoben, und alle zusätzlichen Entwurfszeitargumente werden über diesen Parameter an die Anwendung übergeben.

Eine Entwurfszeit-Factory DbContext kann besonders nützlich sein, wenn Sie die für die Entwurfszeit anders als zur Laufzeit konfigurieren müssen, DbContext wenn der Konstruktor zusätzliche Parameter verwendet, die nicht in der Di registriert sind, wenn Sie überhaupt keine Di verwenden, CreateHostBuilder oder wenn Sie aus irgendeinem Grund keine Methode in der Klasse Ihrer ASP.NET Core-Anwendung Main verwenden möchten.

Args

Und IDesignTimeDbContextFactory<TContext>.CreateDbContext akzeptieren Program.CreateHostBuilder Befehlszeilenargumente.

Ab EF Core 5.0 können Sie diese Argumente aus den Tools angeben:

dotnet ef database update -- --environment Production

Das -- Token leitet an, dotnet ef alles, was folgt, als Argument zu behandeln und nicht zu versuchen, sie als Optionen zu analysieren. Alle zusätzlichen Argumente, die nicht von verwendet dotnet ef werden, werden an die App weitergeleitet.