Domanda

Ho usato Entity Framework 4.3 su un database esistente e ho un paio di scenari che sto cercando di soddisfare.

Innanzitutto, se elimino il mio database, per questo vorrei EF per ricreare se da zero - ho usato correttamente un iniziativa di database creatotabaseifnotexisti per questo.

In secondo luogo, se aggiorno il mio modello e il database esiste già, vorrei che il database fosse aggiornato automaticamente - ho utilizzato correttamente le migrazioni di Entity Framework 4.3 per questo.

Quindi ecco la mia domanda. Supponiamo che aggiungo una nuova tabella al mio modello che richiede alcuni dati di riferimento, qual è il modo migliore per garantire che questi dati vengano creati sia quando il database in tutto il database viene eseguito e anche quando la migrazione viene eseguita. Il mio desiderio è che i dati vengano creati quando sto creando il DB da zero e anche quando il database viene aggiornato come risultato di una migrazione in esecuzione.

In alcuni esempi di migrazioni EF ho visto le persone utilizzare la funzione sql () nel metodo UP della migrazione per creare dati di seme, ma se possibile preferirei usare il contesto per creare i dati delle sementi (come si vede nella maggior parte degli esempi di iniziativa di database) Poiché mi sembra strano che tu useresti puro SQL quando l'intera idea di EF lo sta astratte. Ho provato a utilizzare il contesto nel metodo UP, ma per qualche motivo non pensava che esistesse una tabella creata nella migrazione quando ho provato ad aggiungere i dati delle seed direttamente sotto la chiamata per creare la tabella.

Qualsiasi saggezza molto apprezzata.

È stato utile?

Soluzione

Se si desidera utilizzare le entità per seminare i dati che dovresti utilizzare Seed Metodo nella configurazione delle migrazioni. Se generi un nuovo progetto Enable-Migrations otterrai questa classe di configurazione:

internal sealed class Configuration : DbMigrationsConfiguration<YourContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(CFMigrationsWithNoMagic.BlogContext context)
    {
        //  This method will be called after migrating to the latest version.

        //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
        //  to avoid creating duplicate seed data. E.g.
        //
        //    context.People.AddOrUpdate(
        //      p => p.FullName,
        //      new Person { FullName = "Andrew Peters" },
        //      new Person { FullName = "Brice Lambson" },
        //      new Person { FullName = "Rowan Miller" }
        //    );
        //
    }
}

Il modo in cui i dati sui semi delle migrazioni non sono molto efficienti perché si suppone che vengano utilizzati per una semina molto semplice. Ogni aggiornamento alla nuova versione passerà attraverso l'intero set e proverà ad aggiornare i dati esistenti o inserire nuovi dati. Se non usi AddOrUpdate Metodo di estensione È necessario assicurarsi che i dati siano seminati nel database solo se non sono ancora presenti.

Se desideri un modo efficiente per la semina perché devi seminare molti dati otterrai un risultato migliore con comune:

public partial class SomeMigration : DbMigration
{
    public override void Up()
    {
        ...
        Sql("UPDATE ...");
        Sql("INSERT ...");
    }

    public override void Down()
    {
        ...
    }
}

Altri suggerimenti

Non consiglierei di usare Sql() chiama nel tuo Up() Metodo perché (IMO) questo è davvero destinato al codice di migrazione effettivo per il quale non esiste una funzione integrata, piuttosto che il codice seme.

Mi piace pensare ai dati sui semi come a qualcosa che potrebbe cambiare in futuro (anche se il mio schema non lo fa), quindi scrivo semplicemente controlli "difensivi" attorno a tutti i miei inserti nella funzione del seme per assicurarmi che l'operazione non abbia sparato in precedenza.

Prendi in considerazione uno scenario in cui hai una tabella "tipi" che inizia con 3 voci, ma poi ne aggiungi un quarto. Non dovresti aver bisogno di una "migrazione" per affrontare questo.

Usando Seed() ti dà anche un contesto completo con cui lavorare, il che è molto più bello che usare le stringhe SQL semplici in Sql() Metodo che Ladislav ha dimostrato.

Inoltre, tieni presente che il vantaggio dell'utilizzo di metodi EF integrati sia per il codice di migrazione che per il codice seme è che le operazioni di database rimangono neutrali. Ciò significa che le modifiche allo schema e le domande sono in grado di eseguire su Oracle, Postgre, ecc. Se scrivi SQL RAW reale, allora ti stai potenzialmente bloccando inutilmente.

Potresti essere meno preoccupato per questo poiché il 90% delle persone che usano EF colpirà solo SQL Server, ma lo sto solo buttando là fuori per darti una prospettiva diversa sulla soluzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top