it-swarm.com.de

ASP - Kern Migrieren Sie EF Core SQL DB beim Start

Kann ich mit meiner ASP Core-Web-API sicherstellen, dass die Datenbank mit EF Core auf die neueste Migration migriert wird? Ich weiß, dass dies über die Befehlszeile erfolgen kann, aber ich möchte es programmgesteuert machen.

Update

Basierend auf der Antwort von Janshair Khan kam ich mit dieser Hilfsklasse:

using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using MyWebApi.Models;

namespace MyWebApi
{
    public static class DataSeeder
    {
        public static void SeedData(this IApplicationBuilder app)
        {
            var context = app.ApplicationServices.GetService<MyContext>();

            if (!context.Database.EnsureCreated())
                context.Database.Migrate();
        }
    }
}

Sie können dies über die Configure-Methode in Ihrem Startup.cs wie folgt aufrufen:

app.SeedData();
37
Zeus82

Sie können verwenden

db.Database.EnsureCreated();

um Ihre Datenbank mit Ihrem aktuellen Modell auf den neuesten Stand zu bringen. Wenn Sie Migrationen aktivieren möchten (Wenn nachfolgende Migrationen vermutet werden), verwenden Sie

db.Database.Migrate();

und stellen Sie Ihre nachfolgenden Migrationen im Laufe der Zeit ein.

24
Janshair Khan

Ein Hinweis aus der Dokumentation zum Aufruf von db.Database.EnsureCreated():

Beachten Sie, dass diese API keine Migrationen zum Erstellen der Datenbank verwendet. Im Außerdem kann die erstellte Datenbank später nicht mit .__ aktualisiert werden. Migrationen. Wenn Sie auf eine relationale Datenbank abzielen und .__ verwenden. Migrationen können Sie die DbContext.Database.Migrate () - Methode für .__ verwenden. Stellen Sie sicher, dass die Datenbank erstellt ist und alle Migrationen angewendet werden.

Möglicherweise möchten Sie einfach db.Database.Migrate() aufrufen.

Kommentar aus Quelle entnommen oben Deklaration hier .

29
steamrolla

Verwenden Sie den folgenden Code, um die Migration um auszuführen 

public async void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
    {
        var context = serviceScope.ServiceProvider.GetService<YourContext`enter code here`>();
        context.Database.Migrate();
    }
}
10
chintan310

Basierend auf der Antwort von @steamrolla würde ich folgende Verbesserung vorschlagen:

public static class EnsureMigration
{
    public static void EnsureMigrationOfContext<T>(this IApplicationBuilder app) where T:DbContext
    {
        var context = app.ApplicationServices.GetService<T>();
        context.Database.Migrate();
    }
}

Damit können Sie auch die Migration verschiedener Kontexte sicherstellen, z. wenn Sie eine Identitätsdatenbank haben.

Verwendungszweck:

app.EnsureMigrationOfContext<context>();
4
pisker

Ich habe dies getan, um programmgesteuert mit EF Core 2.1.2 & SQL Server zu migrieren, basierend auf den vorherigen Antworten hier und bailando bailandos Antwort on " Wie und wo kann ich Database.EnsureCreated und Database.Migrate? " aufrufen:

Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;

namespace MyApp
{
    public class Startup
    {
        // ... (only relevant code included) ...

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<MyAppContext>(options => 
                options.UseSqlServer(Configuration.GetConnectionString("MyAppContext")));
            // ...
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            using (var serviceScope = app.ApplicationServices.CreateScope())
            {
                var context = serviceScope.ServiceProvider.GetService<MyAppContext>();
                context.Database.Migrate();
            }
            // ...
        }
    }
}

Das Projekt, das diesen Code verwendet, ist verfügbar bei Github .

0
Lauri Harpf

Dies ist eine geringfügige Korrektur der vorherigen Antwort, durch die eine Erweiterungsmethode erstellt wurde. Es behebt den Fehler, der so ausgegeben wird, wie er geschrieben wurde.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

namespace MyApp.Extensions
{
    public static class IApplicationBuilderExtensions
    {
        public static void SyncMigrations<T>(this IApplicationBuilder app) where T : DbContext
        {
            using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
            {
                var context = serviceScope.ServiceProvider.GetService<DbContext>();
                context.Database.Migrate();
            }
        }
    }
}
0
Dblock247

Basierend auf der Antwort von chintan310 migriere ich die Datenbank. Dies gewährleistet die Trennung datenbankbezogener Aufgaben in Program.cs:

    public static void Main(string[] args)
    {
        var Host = BuildWebHost(args);

        using (var scope = Host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;

            try
            {
                var context = services.GetService<AppDbContext>();
                context.Database.Migrate();

                var seeder = scope.ServiceProvider.GetService<AppSeeder>();
                seeder.Seed().Wait();
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred seeding the DB.");
            }
        }

        Host.Run();
    }

    private static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();
0
Umut Esen