Freigeben über


Entwurfszeit-DbContext-Erstellung

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

Es gibt verschiedene Möglichkeiten, wie die Tools versuchen, folgendes DbContextzu erstellen:

Von Anwendungsdiensten

Wenn Ihr Startprojekt den ASP.NET Core Web Host oder .NET Core Generic Host verwendet, versuchen die Tools, das DbContext-Objekt vom Dienstanbieter der Anwendung abzurufen.

Die Tools versuchen zuerst, den Dienstanbieter abzurufen, indem Program.CreateHostBuilder()sie aufrufen , aufrufen Build()und dann auf die Services Eigenschaft 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)
    {
    }
}

Note

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

Die DbContext Abhängigkeiten in ihrem Konstruktor müssen als Dienste im Dienstanbieter der Anwendung registriert werden. Dies kann ganz einfach erreicht werden, indem ein Konstruktor für die DbContext Instanz DbContextOptions<TContext> als Argument verwendet wird und die AddDbContext<TContext> Methode verwendet wird.

Verwenden eines Konstruktors ohne Parameter

Wenn der DbContext nicht vom Anwendungsdienstanbieter abgerufen werden kann, suchen die Tools nach dem abgeleiteten DbContext Typ innerhalb des Projekts. Anschließend versuchen sie, eine Instanz mit einem Konstruktor ohne Parameter zu erstellen. Dies kann der Standardkonstruktor sein, wenn die DbContext Methode verwendet OnConfiguring wird.

Von einer Entwurfszeitfabrik

Sie können auch die Tools angeben, wie Sie Ihren DbContext erstellen, indem Sie die Microsoft.EntityFrameworkCore.Design.IDesignTimeDbContextFactory<TContext> Schnittstelle implementieren: Wenn eine Klasse, die diese Schnittstelle implementiert, entweder in demselben Projekt wie das abgeleitete DbContext oder im Startprojekt der Anwendung gefunden wird, umgehen die Tools die anderen Methoden zum Erstellen von DbContext und verwenden stattdessen die Entwurfszeitfactory.

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

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

Args

Beide Argumente IDesignTimeDbContextFactory<TContext>.CreateDbContext und Program.CreateHostBuilder akzeptieren Befehlszeilenargumente.

Sie können diese Argumente aus den Tools angeben:

dotnet ef database update -- --environment Production

Das ---Token weist dotnet ef an, alles Nachfolgende als Argument zu behandeln und nicht zu versuchen, es als Optionen zu parsen. Alle zusätzlichen Argumente, die von dotnet ef nicht verwendet werden, werden an die App weitergeleitet.