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.