2016-06-26 34 views
9

Il mio problema è che sto provando a seminare un database Entity Framework Core con i dati e nella mia mente il codice seguente mostra il lavoro. Mi sono reso conto che questo non dovrebbe essere chiamato nel costruttore ApplicationDbContext e dovrebbe essere chiamato dal startup ma non sono sicuro di come farlo.Database dei semi di ASP2NET Core RC2

EDIT: Sulla base della soluzione fornita da Ketrex, la mia soluzione è la seguente:

Startup.cs: estensione

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     ... 

     app.ApplicationServices.GetRequiredService<ApplicationDbContext>().Seed(); 
    } 

Seed:

public static class DbContextExtensions 
{ 
    public static void Seed(this ApplicationDbContext context) 
    { 
     // Perform database delete and create 
     context.Database.EnsureDeleted(); 
     context.Database.EnsureCreated(); 

     // Perform seed operations 
     AddCountries(context); 
     AddAreas(context); 
     AddGrades(context); 
     AddCrags(context); 
     AddClimbs(context); 

     // Save changes and release resources 
     context.SaveChanges(); 
     context.Dispose(); 
    } 

    private static void AddCountries(ApplicationDbContext context) 
    { 
     context.AddRange(
      new Country { Name = "England", Code = "En" }, 
      new Country { Name = "France", Code = "Fr" } 
      ); 
    } 

    ... 
} 

Capisco che semina un il database è abbastanza in alto nella lista delle priorità di Entity Framework ma sarebbe bello se ci fosse qualche documentazione su come raggiungere questo compito banale o almeno fornire un lavoro temporaneo a il giro. Se qualcuno può fornire alcune indicazioni su come farlo, sarebbe molto apprezzato. Mi sento vicino a una soluzione ma non riesco a metterlo insieme.

Grazie per qualsiasi aiuto.

risposta

9

Supponendo che si stia utilizzando il contenitore DI incorporato, ecco un modo per farlo.

di riferimento il metodo di seme nel metodo di configurazione della classe di avvio, e passare l'oggetto IApplicationBuilder come parametro al posto del DbContext, in questo modo:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    //... 
    // Put this at the end of your configure method 
    DbContextSeedData.Seed(app); 
} 

Avanti, modificare il metodo di semi di accettare l'IApplicationBuilder esempio. Allora sarete in grado di girare su un'istanza del DbContext, ed eseguire l'operazione di semi, in questo modo:

public static void Seed(IApplicationBuilder app) 
{ 
    // Get an instance of the DbContext from the DI container 
    using (var context = app.ApplicationServices.GetRequiredService<ApplicationDbContext>()) 
    { 
     // perform database delete 
     context.Database.EnsureDeleted; 
     //... perform other seed operations 
    } 
} 
+0

Grazie mille! Era questa linea 'app.ApplicationServices.GetRequiredService ()' che mi mancava. Ho modificato leggermente la tua soluzione per usarla come metodo di estensione. –

+0

problema: contesto.Database.EnsureDeleted() elimina __EFMigrationsHistory anche !!! –

+1

@MohammadAkbari sembri essere a raccogliere lendini. Notare // ... eseguire altre operazioni di seed linea? Indica chiaramente che potrebbe avere altre operazioni da eseguire. Il problema affrontato qui era l'iniezione del contesto nel metodo seme. – Ketrex

2

Si potrebbe anche usare dal metodo Startup.cs ConfigureServices per rendere il vostro ApplicationDbContext disponibili (Registrazione del DbContext come un servizio):

public void ConfigureServices(IServiceCollection services) 
{ 
    var connectionString = Startup.Configuration["connectionStrings:DBConnectionString"];//this line is not that relevant, the most important thing is registering the DbContext 
      services.AddDbContext<ApplicationDbContext>(o => o.UseSqlServer(connectionString)); 
} 

e quindi aggiungere la tua ApplicationDbContext come dipendenza nel metodo Configure che chiamerà il vostro metodo di estensione seme.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ApplicationDbContext myApplicationDbContext) 
{ 
    //... 
    myApplicationDbContext.Seed(); 
} 

Infine il metodo seme potrebbe fare un rapido controllo su un tavolo importante, perché forse ricreando il db è troppo pesante:

public void Seed() 
{ 
//....  
if(context.Countries.Any()) 
    return; 
//... 
} 

Spero che tu o qualcun altro aiuta, almeno come un altro opzione.

0

Se si desidera eseguire il codice EF da una libreria di classi separata e fare seed in quanto è possibile eseguire quanto segue. Questo sta utilizzando TSQL ...

1) Creare una nuova libreria di classi. Aggiungere le seguenti dipendenze con NuGet ...

Microsoft.AspNetCore 
Microsoft.AspNetCore.Identity.EntityFrameworkCore 
Microsoft.EntityFrameworkCore.SqlServer 
Microsoft.EntityFrameworkCore.Tools 

2) Il punto Console Package Manager a questo progetto ed eseguire ...

PM> add-migration Seeder01 

poi ...

PM> update-database 

questo ti dà una migrazione vuota.

3) Script gli aggiornamenti come qualcosa di simile ...

using Microsoft.EntityFrameworkCore; 
using Microsoft.EntityFrameworkCore.Migrations; 
using System; 
using System.Collections.Generic; 
using Microsoft.Extensions.Configuration; 
using System.IO; 

namespace Test02.Data.Migrations 
{ 
    public partial class Seeder01 : Migration 
    { 

     protected override void Up(MigrationBuilder migrationBuilder) 
     { 
      string sql = string.Empty; 

      sql = "SET IDENTITY_INSERT State ON;"; 
      sql += "Insert into State (Id, Name) values "; 
      sql += "(2, 'NSW'),"; 
      sql += "(3, 'VIC'),"; 
      sql += "(4, 'QLD'),"; 
      sql += "(5, 'SA')"; 
      sql += ";"; 
      sql += "SET IDENTITY_INSERT State OFF;"; 
      migrationBuilder.Sql(sql); 

     } 

     protected override void Down(MigrationBuilder migrationBuilder) 
     { 
      string sql = string.Empty; 
      sql = "delete State;"; 
      migrationBuilder.Sql(sql); 


     } 
    } 
} 

4) tornare alla migrazione precedente con ...

PM> add-migration {PriorMigrationName} 

Ricarica la migrazione seme e aggiornare il database ..

PM> add-migration Seeder01 
PM> update-database 
Problemi correlati