2012-02-18 10 views
41

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

Po pierwsze, jeśli usunę moją bazę danych, chciałabym, aby EF była odtwarzana od zera - z powodzeniem użyłem do tego inicjatora bazy danych CreateDatabaseIfNotExists.

Po drugie, jeśli zaktualizuję mój model, a baza danych już istnieje, chciałbym, aby baza danych została automatycznie zaktualizowana - z powodzeniem zastosowałem do tego celu Entity Framework 4.3 Migrations.

Oto moje pytanie. Załóżmy, że dodaję do mojego modelu nową tabelę, która wymaga pewnych danych referencyjnych, co jest najlepszym sposobem zapewnienia, że ​​dane te zostaną utworzone zarówno podczas uruchamiania inicjatora bazy danych, jak i podczas migracji. Moją wolą jest, aby dane były tworzone podczas tworzenia bazy danych od zera, a także gdy baza danych zostanie zaktualizowana w wyniku przeprowadzonej migracji.

W niektórych przykładach migracji EF korzystałem z funkcji SQL() w metodzie UP migracji, aby utworzyć dane źródłowe, ale jeśli to możliwe, wolałbym użyć kontekstu do utworzenia danych źródłowych (jak widać w większości bazy danych przykładów inicjalizujących), ponieważ wydaje mi się dziwne, że używałbyś czystego sql, gdy cała idea EF wyrzeka się tego. Próbowałem użyć kontekstu w metodzie UP, ale z jakiegoś powodu nie sądziłem, że tabela utworzona podczas migracji istniała, gdy próbowałem dodać dane źródłowe bezpośrednio pod wywołaniem, aby utworzyć tabelę.

Dowolna mądrość doceniona.

Odpowiedz

53

Jeśli chcesz użyć elementów do zaszczepienia danych, powinieneś użyć metody Seed w swojej konfiguracji migracji. Jeśli wygenerowania nowego projektu Enable-Migrations dostaniesz tej klasy 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 dane migracje nasienne nie są bardzo wydajne, ponieważ ma być używany przez pewien bardzo prosty siewu. Każda aktualizacja 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ą rozsiane do bazy danych tylko wtedy, gdy nie są jeszcze dostępne.

Jeśli chcesz efektywną drogę do wysiewu nasion, ponieważ trzeba dużo danych o, można uzyskać lepsze wyniki ze wspólnego:

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

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

Można faktycznie utworzyć kontekst w metodzie Up i użyć AddOrUpdate do wstawienia wierszy. Nie spowoduje to jednak zawarcia transakcji migracji, może więc powodować problemy. Nie można też zagwarantować kompilacji w przyszłości, gdy model ulegnie zmianie. – Betty

+0

Próbowałem utworzyć kontekst w metodzie Up, ale wystąpił błąd informujący, że tabela nie istnieje. Zamiast tego wypróbuję SQL w metodzie "Up". –

+8

@Ladislav Twoja głębia wiedzy na temat EF nadal mnie zadziwia, czy zastanawiałeś się nad napisaniem książki na ten temat i być może na temat częstych nieporozumień, które tu napotykasz? – kingdango

32

Nie polecam korzystania Sql() połączeń w swojej metodzie Up() ponieważ (IMO) jest to rzeczywiście przeznaczone dla rzeczywistego kodu migracji, dla którego nie ma wbudowanej funkcji, a nie kodu źródłowego.

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 ma), więc po prostu piszę "obronne" kontrole wokół wszystkich moich wkładek w funkcji nasion, aby upewnić się, że operacja nie była wcześniej uruchamiana.

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

Korzystanie z 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 korzyści wynikające z zastosowania wbudowanych metod EF zarówno w odniesieniu do kodu migracji, jak i kodu źródłowego są takie, że operacje na bazach danych pozostają neutralne dla platformy. Oznacza to, że zmiany schematu i zapytania mogą być uruchamiane w Oracle, Postgre itp. Jeśli napiszesz rzeczywisty surowy SQL, możesz potencjalnie zablokować się niepotrzebnie.

Być może mniej się o to martwisz, ponieważ 90% osób korzystających z EF uderzy tylko w SQL Server, ale po prostu wyrzucam go, aby dać ci inną perspektywę rozwiązania.

+7

Myślę, że metoda "Up" jest dobrym miejscem do robienia danych "Reference" - dane referencyjne na ogół oznaczają, że aplikacja potrzebuje tych danych dla jakiejś logiki. – nootn

Powiązane problemy