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