2016-03-15 12 views
7

Sto provando a generare automaticamente il mio database se non esiste ed eseguire il metodo Seed() per popolare i dati. Nel mio costruttore contesto di database ho questo:MigrateDatabaseToLatestVersion senza metodo Seed()

Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDBContext, Configuration>()); 

Questa grande opera, il mio database viene creato automaticamente con tutte le tabelle come voglio, ma sembra che il metodo Seed() non viene chiamato, il mio database è vuoto. Questa è la mia classe:

internal sealed class Configuration : DbMigrationsConfiguration<Context.MyDBContext> 
{ 

    public Configuration() 
    { 
     AutomaticMigrationsEnabled = true; 
    } 

    protected override void Seed(Context.MyDBContext context) 
    { 
     context.Users.AddOrUpdate(
      new Entities.User() { Email = "[email protected]", Password = "", Language = "en", CreatedDate = DateTime.Now } 
     ); 

     base.Seed(context); 
    } 
} 

Quando eseguo Update-Database nella console Nuget il dati viene popolata dopo la creazione del database, ma con il metodo MigrateDatabaseToLatestVersionSeed() non viene chiamato.

Cosa può succedere? Ho provato a fare funzionare manualmente migrazioni come preso da here:

var configuration = new MyDbContextConfiguration(); 
configuration.TargetDatabase = new DbConnectionInfo(
    database.ConnectionString, database.ProviderName); 

var migrator = new DbMigrator(configuration); 
migrator.Update(); 

Ma anche non funziona.


EDIT:

Ok, dopo un po 'di più test ho trovato che la Seed() corre metodo, ma solo quando il database esiste già, cioè, al primo periodo, quando viene creato il database per il la prima volta il metodo Seed() non viene eseguito, ma quando eseguo la mia app la seconda volta viene eseguito Seed() get. Ho anche dovuto aggiungere context.SaveChanges() in modo per farlo funzionare (grazie a @DavidG nei commenti):

protected override void Seed(Context.MyDBContext context) 
    { 
     context.Users.AddOrUpdate(
      new Entities.User() { Email = "[email protected]", Password = "", Language = "en", CreatedDate = DateTime.Now } 
     ); 

     context.SaveChanges(); 
     base.Seed(context); 
    } 

Così forse posso chiamare manualmente Seed() all'interno Configuration() e fare un po 'il controllo per evitare di aggiungere i dati duplicazione o la modifica dei dati quello esiste già.

+0

non funziona non è sufficiente. Hai provato ad entrare in un debugger? Viene chiamato il metodo Seed? Se lo è, il problema potrebbe essere tentare di inizializzare un utente in questo modo. Usa UserManager invece –

+0

Puoi lanciare un'eccezione nel metodo 'Seed' per verificare che il metodo seed non sia stato eseguito affatto (e non che semplicemente l'utente non sia stato inserito nel database?). – Rob

+0

Non si sta chiamando 'context.SaveChanges();' dopo aver aggiunto gli utenti. – DavidG

risposta

7

Ho finito con questa classe Configuration:

public class Configuration : DbMigrationsConfiguration<Context.MyDBContext> 
    { 
     private readonly bool _pendingMigrations; 

     public Configuration() 
     { 
      AutomaticMigrationsEnabled = true; 

      // Check if there are migrations pending to run, this can happen if database doesn't exists or if there was any 
      // change in the schema 
      var migrator = new DbMigrator(this); 
      _pendingMigrations = migrator.GetPendingMigrations().Any(); 

      // If there are pending migrations run migrator.Update() to create/update the database then run the Seed() method to populate 
      // the data if necessary 
      if (_pendingMigrations) 
      { 
       migrator.Update(); 
       Seed(new Context.MyDBContext()); 
      } 
     } 

     protected override void Seed(Context.MyDBContext context) 
     { 
      // Microsoft comment says "This method will be called after migrating to the latest version." 
      // However my testing shows that it is called every time the software starts 

      // Run whatever you like here 

      // Apply changes to database 
      context.SaveChanges(); 
      base.Seed(context); 
     } 
    } 

Così in questo modo il metodo di Seed() viene chiamato quando viene creato il database e anche quando non ci sono in attesa di migrazioni.

Questo è il mio MyDBContext classe:

public class MyDBContext: DbContext 
{ 
    public MyDBContext() : base(AppSettings.DBConnectionString) 
    { 
    } 

    public static MyDBContext Create() 
    { 
     return new MyDBContext(); 
    } 

    public DbSet<User> Users { get; set; } 
    public DbSet<Entries> Entries { get; set; } 
} 
+0

Ho lo stesso problema, ma la tua soluzione crea un loop infinito per me. Per essere specifici questa parte 'Seed (new Context.MyDBContext());' Crea un nuovo 'DbContext' che crea una nuova' Configuratio' che crea un nuovo 'DbContext' e così via fino all'eccezione StackOverflow – Masius

+0

Vedere l'esempio' MyDBContext' class I aggiunto alla risposta. Per me funziona perfettamente in un ambiente di produzione senza problemi. – Andres

+0

Dove 'Database.SetInitializer (new MigrateDatabaseToLatestVersion ());' ora dovrebbe essere chiamato - manca nel costruttore 'MyDbContext'? – pitersmx

Problemi correlati