Najlepszy sposób na przyrostowe zalążki danych w ramach jednostki 4.3

Używam Entity Framework 4.3 na istniejącej bazie danych i mam kilka scenariuszy, które staram się zaspokoić.

Po pierwsze, jeśli usunę swoją bazę danych, chciałbym EF odtworzyć, jeśli od zera - z powodzeniem użyłem do tego inicjalizatora bazy danych CreateDatabaseIfNotExists.

Po drugie, jeśli zaktualizuję swój model i baza danych już istnieje, chciałbym, aby baza danych była aktualizowana automatycznie - z powodzeniem korzystałem z Entity Framework 4.3 Migracje do tego.

Oto moje pytanie. Powiedzmy, że dodaję nową tabelę do mojego modelu, która wymaga pewnych danych referencyjnych, co jest najlepszym sposobem, aby zapewnić, że dane te zostaną utworzone zarówno podczas uruchamiania intializera bazy danych, jak i podczas migracji. Moim pragnieniem jest, aby dane były tworzone, gdy tworzę bazę danych od podstaw, a także gdy baza danych zostanie zaktualizowana w wyniku migracji.

W niektórych przykładach migracji EF widziałem, że ludzie używają funkcji SQL() w metodzie UP migracji do tworzenia danych seed, ale jeśli to możliwe, wolałbym użyć kontekstu do tworzenia danych seed (jak widać w większości przykładów inicjalizacji bazy danych) , ponieważ wydaje mi się dziwne, że użyłbyś czystego sql, gdy cała idea EF jest abstrakcja, że daleko. Próbowałem użyć kontekstu w metodzie UP, ale z jakiegoś powodu nie wydawało mi się, że istnieje tabela, która została utworzona podczas migracji, gdy próbowałem dodać dane seed bezpośrednio pod wywołaniem, aby utworzyć stolik.

Każda mądrość jest bardzo doceniana.

Author: Ladislav Mrnka, 2012-02-18

2 answers

Jeśli chcesz użyć encji do zalążkowania danych, powinieneś użyć metody Seed w konfiguracji migracji. Jeśli wygenerujesz nowy projekt Enable-Migrations otrzymasz klasę konfiguracji:

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" }
        //    );
        //
    }
}

Sposób, w jaki migracje danych nasiennych nie są zbyt wydajne, ponieważ powinny być używane do pewnego bardzo podstawowego siewu. Każda aktualizacja do nowej wersji przechodzi przez cały zestaw i próbuje zaktualizować istniejące dane lub wstawić nowe dane. Jeśli nie używasz metody rozszerzenia AddOrUpdate, musisz ręcznie upewnić się, że dane są przesyłane do bazy danych tylko wtedy, gdy nie są jeszcze obecne.

Jeśli chcesz efektywny sposób siewu, ponieważ musisz seed dużo danych, otrzymasz lepszy wynik z common:

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

    public override void Down()
    {
        ...
    }
}
 54
Author: Ladislav Mrnka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-18 19:08:46

Nie zalecałbym używania wywołań Sql() w Twojej metodzie Up(), ponieważ (IMO) jest to naprawdę przeznaczone dla rzeczywistego kodu migracji, dla którego nie ma wbudowanej funkcji, a nie kodu zalążkowego.

Lubię myśleć o danych nasion jako o czymś, co może się zmienić w przyszłości (nawet jeśli mój schemat nie), więc po prostu piszę" defensywne " kontrole wokół wszystkich moich wstawek w funkcji nasion, aby upewnić się, że operacja nie odpaliła się wcześniej.

Rozważ scenariusz, w którym masz Tabela" typy", która zaczyna się od 3 wpisów, ale później dodajesz 4. Nie powinieneś potrzebować "migracji", aby rozwiązać ten problem.

Użycie Seed() daje również pełny kontekst do pracy, który jest o wiele ładniejszy niż użycie zwykłych łańcuchów sql w metodzie Sql(), którą zademonstrował Ladislav.

Należy również pamiętać, że zaletą stosowania wbudowanych metod EF zarówno dla kodu migracji, jak i kodu zalążkowego jest to, że operacje bazy danych pozostają neutralne dla platformy. Oznacza to, że twój schemat zmiany i zapytania mogą być uruchamiane na Oracle, Postgre itp. Jeśli piszesz rzeczywisty surowy SQL, potencjalnie niepotrzebnie się blokujesz.

Możesz być mniej zaniepokojony tym, ponieważ 90% osób korzystających z EF trafi tylko na SQL Server, ale po prostu rzucam go tam, aby dać ci inne spojrzenie na rozwiązanie.

 32
Author: Roger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-11 08:09:10