2016-07-07 142 views
18

Ho un'applicazione ASP.NET MVC 6 e ho bisogno di chiamare i metodi Database.EnsureCreated e Database.Migrate.Come e dove chiamare Database.EnsureCreated e Database.Migrate?

Ma dove dovrei chiamarli?

+0

Non si può desiderare di utilizzare neanche. I documenti MS dicono sull'utilizzo di Migrate(): "Sebbene sia ideale per le app con un database locale, la maggior parte delle applicazioni richiederà una strategia di implementazione più robusta come la generazione di script SQL". https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/ –

risposta

6

Proprio come una prefazione si dovrebbe leggere this da Rowan Miller:

... EnsureCreated aggira completamente le migrazioni e crea solo la schema per voi, non è possibile mescolare questo con le migrazioni. EnsureCreated è progettato per il test o la prototipazione rapida, in cui si sta bene con interrompendo e ricreando il database ogni volta. Se si utilizzano le migrazioni e si desidera che vengano automaticamente applicate all'avvio dell'app, , è possibile utilizzare invece context.Database.Migrate().

Secondo rispondere here è necessario aggiungere Globals.EnsureDatabaseCreated(); a Startup.cs:

funzione di avvio in Startup.cs:

public Startup(IHostingEnvironment env) 
{ 
    // Set up configuration sources. 
    var builder = new ConfigurationBuilder() 
      .AddJsonFile("appsettings.json") 
      .AddEnvironmentVariables(); 

    if (env.IsDevelopment()) 
    { 
     // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately. 
      builder.AddApplicationInsightsSettings(developerMode: true); 
    } 
    Configuration = builder.Build(); 
    Globals.Configuration = Configuration; 
    Globals.HostingEnvironment = env; 
    Globals.EnsureDatabaseCreated(); 
} 

E definire Globals.EnsureDatabaseCreated() come segue:

public static void EnsureDatabaseCreated() 
    { 
     var optionsBuilder = new DbContextOptionsBuilder(); 
     if (HostingEnvironment.IsDevelopment()) optionsBuilder.UseSqlServer(Configuration["Data:dev:DataContext"]); 
     else if (HostingEnvironment.IsStaging()) optionsBuilder.UseSqlServer(Configuration["Data:staging:DataContext"]); 
     else if (HostingEnvironment.IsProduction()) optionsBuilder.UseSqlServer(Configuration["Data:live:DataContext"]); 
     var context = new ApplicationContext(optionsBuilder.Options); 
     context.Database.EnsureCreated(); 

     optionsBuilder = new DbContextOptionsBuilder(); 
     if (HostingEnvironment.IsDevelopment()) optionsBuilder.UseSqlServer(Configuration["Data:dev:TransientContext"]); 
     else if (HostingEnvironment.IsStaging()) optionsBuilder.UseSqlServer(Configuration["Data:staging:TransientContext"]); 
     else if (HostingEnvironment.IsProduction()) optionsBuilder.UseSqlServer(Configuration["Data:live:TransientContext"]); 
     new TransientContext(optionsBuilder.Options).Database.EnsureCreated(); 
    } 

Per utilizzare context.Database.Migrate(), vedere here o here.

+0

Ciao James, grazie per la tua risposta !, non ho alcun accesso a un nome vorticoso Globals nella mia startup metodo, come posso accedervi? –

19

Penso che questa sia una domanda importante e dovrebbe essere ben fornita!

Che cos'è ConfirmCreated?

ConfirmCreated è un nuovo metodo di base EF che garantisce l'esistenza del database per il contesto. Se esiste, non viene intrapresa alcuna azione. Se non esiste, vengono creati il ​​database e tutti i relativi schemi e inoltre si assicura che sia compatibile con il modello per questo contesto.

Nota: Questo metodo non utilizza le migrazioni per creare il database. Inoltre, il database creato non può essere aggiornato successivamente utilizzando le migrazioni. Se si sta prendendo di mira un database relazionale e si utilizzano le migrazioni, è possibile utilizzare il metodo DbContext.Database.Migrate() per garantire che il database sia stato creato e tutte le migrazioni vengano applicate.

Come abbiamo fatto con EF 6?

EnsureCreated è equivalente agli approcci di seguito elencati di EF 6:

  1. Package Manager Console:

    Enable-Migrazioni -EnableAutomaticMigrations. Aggiungere-migrazione/Update-Database.

  2. Da codice:

    Database.SetInitializer CreateDatabaseIfNotExists

o

Con DbMigrationsConfiguration e impostare AutomaticMigrationsEnabled = true;

Che cos'è Database.Migrate?

Applica qualsiasi migrazione in sospeso per il contesto al database. Creerà il database se non esiste già.

Come abbiamo fatto con EF 6?

context.Database.Migrate() è equivalente agli approcci di seguito elencati di EF 6:

  1. Package Manager Console:

    Update-Database -TargetMigration

  2. Con una DbMigrationsConfiguration personalizzata:

    AutomaticMigrat ionsEnabled = false; o con DbMigrator.

Conclusione:

Se si utilizza migrazioni c'è context.Database.Migrate(). Se non vuoi migrazioni e vuoi solo un database veloce (di solito per i test), usa context.Database.EnsureCreated()/GuaranteDeleted().

+2

Ciao Bassam Alugili, grazie per la tua risposta! nel mio progetto, sto usando le migrazioni, non sapevo che non si dovrebbero usare entrambi i metodi insieme. –

+1

e qui c'è un esempio su come chiamarlo! http://www.stefanhendriks.com/2016/04/29/integration-testing-your-dot-net-core-app-with-an-in-memory-database/ –

+0

Stavo pensando che 'Database.Migrate () 'crea le migrazioni (se necessario) quindi aggiorna la base basata su di esso. Proprio simile alla migrazione automatica in EF 6. Ma mi sbagliavo. Applica solo le migrazioni esistenti (se presenti) sul database. –

5

Con le informazioni fornite da James P e Bassam Alugili, ciò che ho finito è stato aggiungere queste righe di codice al metodo Startup.cs-> Configure.

try 
      { 
       using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>() 
        .CreateScope()) 
       { 

        serviceScope.ServiceProvider.GetService<ApplicationDbContext>() 
         .Database.Migrate(); 
       } 
      } 
      catch (Exception e) 
      { 
       var msg = e.Message; 
       var stacktrace = e.StackTrace; 
      }