2013-10-07 5 views
5

mi chiedevo se qualcuno ha riscontrato un problema simile:generazione di codice seme da database esistente in ASP.NET MVC

Ho un database con alcuni dati che era ETL'ed (importata e trasformata) in là da un Excel file. Nella mia applicazione web ASP.NET MVC che sto utilizzando codice Primo approccio e far cadere/creando ogni volta che le modifiche al database:

#if DEBUG 
    Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyDataContext>()); 
#endif 

Tuttavia, dal momento che i dati presenti nel database è perso, devo Etl di nuovo, il che è fastidioso

Dato che il DB verrà abbandonato solo per il cambio di modello, dovrò comunque modificare il mio ETL, lo so. Ma preferirei cambiare il mio codice seme DB.

Qualcuno sa come prelevare il contenuto del database e generare il codice di inizializzazione, presupponendo che sia i modelli che le tabelle SQL siano aggiornati?

EDIT 1: Sto pensando di utilizzare l'auto-generata Configuration.cs, e il suo metodo di semi, e quindi utilizzare AddOrUpdate() metodo per aggiungere dati nel database: Ecco Microsoft's Tutorial on migrations (in particolare il "Set up la sezione "metodo Seed").

+0

Cosa intendi per "codice seme"? –

+0

Ho aggiunto una spiegazione alla mia domanda. –

risposta

5

Un altro modo per eseguire il seeding dei dati è eseguirlo come sql in una migrazione Up.

Ho codice che leggerà un file sql ed eseguirlo

using System; 
using System.Data.Entity.Migrations; 
using System.IO; 

public partial class InsertStandingData : DbMigration 
{ 
    public override void Up() 
    { 
     var baseDir = AppDomain.CurrentDomain 
           .BaseDirectory 
           .Replace("\\bin", string.Empty) + "\\Data\\Sql Scripts"; 

     Sql(File.ReadAllText(baseDir + "\\StandingData.sql")); 
    } 

    public override void Down() 
    { 
     //Add delete sql here 
    } 
} 

Così, se l'ETL genera SQL per voi allora si potrebbe usare quella tecnica.

I vantaggi di farlo nel metodo Up sono

  1. Sarà più veloce che farlo usando AddOrUpdate perché AddOrUpdate interroga il database ogni volta che viene chiamato per ottenere qualsiasi entità già esistenti.
  2. Si sta normalmente passando da uno stato noto (ad esempio tabelle vuote), quindi probabilmente non è necessario verificare se i dati sono già disponibili. NB per garantire questo , è necessario eliminare i dati nel metodo Down in modo che sia possibile eseguire lo strappo fino in fondo e di nuovo su di nuovo.
  3. Il metodo Up non viene eseguito ad ogni avvio dell'applicazione.

Il metodo Seed fornisce praticità - e ha il vantaggio (!?) Che viene eseguito ogni volta che l'applicazione si avvia

Ma se si preferisce eseguire l'SQL da lì utilizzare ExecuteSqlCommand invece di Sql:

string baseDir = AppDomain.CurrentDomain.BaseDirectory.Replace("\\bin", string.Empty) 
       + "\\Data\\Sql Scripts"; 
string path = Path.Combine(baseDir, "StandingData"); 
foreach (string file in Directory.GetFiles(path, "*.sql")) 
{ 
    context.Database.ExecuteSqlCommand(File.ReadAllText(file)); 
} 

Riferimenti:

Best way to incrementally seed data

Preparing for database deployment

Database Initializer and Migrations Seed Methods

+0

Da quale spazio dei nomi è il metodo Sql? –

+0

È nello stesso spazio dei nomi di 'DbMigration'! Risposta modificata per mostrare la classe e utilizzare le istruzioni – Colin

+0

Quindi i metodi su e giù vengono eseguiti solo sul drop del database? –

4

Diciamo che abbiamo una semplice tabella di database con i record ;

| Id | Age | FullName  | 
|------|-----|-----------------| 
| 1 | 50 | Michael Jackson | 
| 2 | 42 | Elvis Presley | 
| 3 | 48 | Whitney Houston | 
| ... | ... | ...    | 
| 3750 | 57 | Prince   | 

Vogliamo creare questa tabella nel nostro database con l'utilizzo di auto-generata Configuration.cs file e il suo metodo Seed().

protected override void Seed(OurDbContainer context) 
{ 
    context.GreatestSingers.AddOrUpdate(
      p => p.Id, 
      new GreatestSinger { Id = 1, Age = 50, FullName = "Michael Jackson" }, 
      new GreatestSinger { Id = 2, Age = 42, FullName = "Elvis Presley" }, 
      new GreatestSinger { Id = 3, Age = 48, FullName = "Whitney Houston" } 
      ); 
} 

Questo è quello che dovresti fare. volte!

Ma questi dati sono già presenti nella tabella di database esistente. Quindi possiamo usare questo dati esistenti per creare i codici Seed().

Con l'aiuto di SQL String Concatenation;

SELECT 
CONCAT('new GreatestSinger { Id = ', Id ,', Age = ', Age ,', FullName = "', FullName ,'" },') 
FROM GreatestSinger 

ci darà tutto il codice necessario per creare righe di dati.

Basta copiare/incollare nel metodo Seed(). E dalla console Package Manager;

Add-Migration SeedDBwithSingersData 

Update-Database