DbContext-Instanzerstellung zur EntwurfszeitDesign-time DbContext Creation

Einige der EF Core Tools-Befehle (z. b. die Migrations Befehle) erfordern, dass eine abgeleitete DbContext Instanz zur Entwurfszeit erstellt wird, um Details zu den Entitäts Typen der Anwendung und deren Zuordnung zu einem Datenbankschema zu erfassen.Some of the EF Core Tools commands (for example, the Migrations commands) require a derived DbContext instance to be created at design time in order to gather details about the application's entity types and how they map to a database schema. In den meisten Fällen ist es wünschenswert, dass die, die DbContext erstellt wird, auf ähnliche Weise konfiguriert wird, wie Sie zur Laufzeit konfiguriertwird.In most cases, it is desirable that the DbContext thereby created is configured in a similar way to how it would be configured at run time.

Es gibt verschiedene Möglichkeiten, die Tools zu erstellen DbContext :There are various ways the tools try to create the DbContext:

Aus AnwendungsdienstenFrom application services

Wenn das Startprojekt den ASP.net Core Webhost oder den generischen .net Core-Hostverwendet, versuchen die Tools, das dbcontext-Objekt vom Dienstanbieter der Anwendung abzurufen.If your startup project uses the ASP.NET Core Web Host or .NET Core Generic Host, the tools try to obtain the DbContext object from the application's service provider.

Die Tools versuchen zunächst, den Dienstanbieter Program.CreateHostBuilder() abzurufen, indem Sie aufrufen und dann auf die- Build() Services Eigenschaft zugreifen.The tools first try to obtain the service provider by invoking Program.CreateHostBuilder(), calling Build(), then accessing the Services property.

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 class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

Hinweis

Wenn Sie eine neue ASP.net Core Anwendung erstellen, ist dieser Hook standardmäßig enthalten.When you create a new ASP.NET Core application, this hook is included by default.

Die DbContext selbst und alle Abhängigkeiten im Konstruktor müssen als Dienste im Dienstanbieter der Anwendung registriert werden.The DbContext itself and any dependencies in its constructor need to be registered as services in the application's service provider. Dies kann problemlos erreicht werden, indem ein Konstruktor für den verwendet wird DbContext , der eine Instanz von DbContextOptions<TContext> als Argument annimmt und die- AddDbContext<TContext> Methodeverwendet.This can be easily achieved by having a constructor on the DbContext that takes an instance of DbContextOptions<TContext> as an argument and using the AddDbContext<TContext> method.

Verwenden eines Konstruktors ohne ParameterUsing a constructor with no parameters

Wenn dbcontext vom Anwendungs Dienstanbieter nicht abgerufen werden kann, suchen die Tools im Projekt nach dem abgeleiteten DbContext Typ.If the DbContext can't be obtained from the application service provider, the tools look for the derived DbContext type inside the project. Anschließend wird versucht, eine Instanz mit einem Konstruktor ohne Parameter zu erstellen.Then they try to create an instance using a constructor with no parameters. Dies kann der Standardkonstruktor sein, wenn DbContext mithilfe der- OnConfiguring Methode konfiguriert wird.This can be the default constructor if the DbContext is configured using the OnConfiguring method.

Aus einer Entwurfszeit FactoryFrom a design-time factory

Sie können den Tools auch mitteilen, wie Sie dbcontext durch Implementieren der- IDesignTimeDbContextFactory<TContext> Schnittstelle erstellen: Wenn eine Klasse, die diese Schnittstelle implementiert, sich im gleichen Projekt wie die abgeleitete DbContext oder im Startprojekt der Anwendung befindet, umgehen die Tools die anderen Methoden zum Erstellen von dbcontext und verwenden stattdessen die entwurfszeitfactory.You can also tell the tools how to create your DbContext by implementing the IDesignTimeDbContextFactory<TContext> interface: If a class implementing this interface is found in either the same project as the derived DbContext or in the application's startup project, the tools bypass the other ways of creating the DbContext and use the design-time factory instead.

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).Prior to EFCore 5.0 the args parameter was unused (see this issue). Dies wird in efcore 5,0 korrigiert, und alle zusätzlichen Entwurfszeit Argumente werden über diesen Parameter an die Anwendung übergeben.This is fixed in EFCore 5.0 and any additional design-time arguments are passed into the application through that parameter.

Eine Entwurfszeit Factory kann besonders nützlich sein, wenn Sie dbcontext zur Entwurfszeit anders konfigurieren müssen als zur Laufzeit, wenn der DbContext Konstruktor zusätzliche Parameter nicht in di registriert ist, wenn Sie di überhaupt nicht verwenden oder wenn Sie aus irgendeinem Grund keine CreateHostBuilder Methode in der Klasse der ASP.net Core Anwendung verwenden möchten Main .A design-time factory can be especially useful if you need to configure the DbContext differently for design time than at run time, if the DbContext constructor takes additional parameters are not registered in DI, if you are not using DI at all, or if for some reason you prefer not to have a CreateHostBuilder method in your ASP.NET Core application's Main class.

ArgsArgs

Sowohl idesigntimedbcontextfactory. kreatedbcontext als auch Program. deatehostbuilder akzeptieren Befehlszeilenargumente.Both IDesignTimeDbContextFactory.CreateDbContext and Program.CreateHostBuilder accept command line arguments.

Ab EF Core 5,0 können Sie diese Argumente in den Tools angeben:Starting in EF Core 5.0, you can specify these arguments from the tools:

dotnet ef database update -- --environment Production

Das -- Token leitet dotnet ef , um alle nachfolgenden Elemente als Argument zu behandeln, und versucht nicht, Sie als Optionen zu analysieren.The -- token directs dotnet ef to treat everything that follows as an argument and not try to parse them as options. Alle zusätzlichen Argumente, die nicht von verwendet dotnet ef werden, werden an die APP weitergeleitet.Any extra arguments not used by dotnet ef are forwarded to the app.