Tervezési időbeli DbContext létrehozása

Az EF Core Tools egyes parancsai (például a Migrálási parancsok) megkövetelik, hogy tervezéskor származtatott DbContext példányt hozzanak létre az alkalmazás entitástípusairól és az adatbázisséma leképezésének módjáról részletek gyűjtése érdekében. A legtöbb esetben kívánatos, hogy az DbContext így létrehozott konfigurálás a futásidőben történő konfigurálás módjához hasonlóan legyen konfigurálva.

Az eszközök többféleképpen próbálják létrehozni a következőt DbContext:

Alkalmazásszolgáltatásokból

Ha az indítási projekt a ASP.NET Core Web Host vagy a .NET Core Generic Gazdagépet használja, az eszközök megpróbálják beszerezni a DbContext objektumot az alkalmazás szolgáltatójától.

Az eszközök az első lépéstől kezdve a következőket teszik: először megpróbálják beolvasni a szolgáltatót, majd meghívják Program.CreateHostBuilder(), hívják Build(), és végül hozzáférnek Services tulajdonsághoz.

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

Új ASP.NET Core-alkalmazás létrehozásakor a rendszer alapértelmezés szerint ezt a horgot tartalmazza.

Magát DbContext és a konstruktorban lévő függőségeket szolgáltatásként kell regisztrálni az alkalmazás szolgáltatójában. Ez könnyen megvalósítható, ha egy konstruktort hoz létre a DbContext, amely egy DbContextOptions<TContext> példányt vesz argumentumként, és használja a AddDbContext<TContext> metódust.

Konstruktor használata paraméterek nélkül

Ha a DbContext nem kérhető le az alkalmazásszolgáltatótól, az eszközök a projekten belül keresik a származtatott típust DbContext . Ezután megpróbálnak létrehozni egy példányt paraméterek nélküli konstruktor használatával. Ez lehet az alapértelmezett konstruktor, ha a DbContext metódussal OnConfiguring van konfigurálva.

Tervezési időben használt gyárból

A DbContext létrehozásának módját az interfész implementálásával Microsoft.EntityFrameworkCore.Design.IDesignTimeDbContextFactory<TContext> is megadhatja: Ha egy osztály, amely megvalósítja ezt az interfészt, megtalálható akár ugyanabban a projektben, mint a származtatott DbContext, akár az alkalmazás indítási projektjében, az eszközök megkerülik a DbContext létrehozásának egyéb módjait, és ehelyett a tervezési idejű gyári osztályt használják.

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

A tervezési idő gyár különösen akkor lehet hasznos, ha a DbContext-t a tervezési időben másképp kell konfigurálni, mint a futásidőben, ha a DbContext konstruktor további paramétereket vesz fel, amelyek nincsenek regisztrálva a DI-ben, ha egyáltalán nem használ DI-t, vagy ha valamilyen okból nem kíván metódust CreateHostBuilder használni az ASP.NET Core-alkalmazás Main osztályában.

Args

Mind a IDesignTimeDbContextFactory<TContext>.CreateDbContext, mind a Program.CreateHostBuilder elfogadja a parancssori argumentumokat.

Ezeket az argumentumokat az eszközökből adhatja meg:

dotnet ef database update -- --environment Production

A -- jogkivonat arra utasítja dotnet ef-et, hogy az utána következőket argumentumként kezelje, és ne próbálja meg opciókként elemezni őket. A dotnet ef által nem használt további argumentumokat a rendszer továbbítja az alkalmazásnak.