2015-02-20 29 views
6

Używam Entity Framework 6 i używam migracji. Utworzono już bazę danych przy użyciu początkowej migracji. Teraz dokonałem zmian w Modelu i kontekst się zmienił i chcę zaktualizować bazę danych ALE ... Gdy próbuję ponownie uruchomić komendę Database-Update, nasiona również są uruchomione, co powoduje błędy z powodu pewnych danych wstawiony ponownie.EF6 - Uruchom polecenie aktualizacji bazy danych bez nasion

Jak mogę uruchomić komendę Update-Database BEZ uruchamiania metody seed?


Trudno uwierzyć, że EF nie ma do tego żadnej prostej opcji, takiej jak -No-Seed. Jestem prawie bezpieczny, że robią to inne ORMy.

+1

Czy używasz metody rozszerzającej 'AddOrUpdate'? – octavioccl

+0

Nop, nie używam 'AddOrUpdate' dla wszystkich wstawek nasion, oprócz tego istnieją surowe skrypty slq. –

+0

http://stackoverflow.com/a/20245687/150342 – Colin

Odpowiedz

7

z kodu źródłowego DbMigrationsConfiguration<TContext>:

/// <summary> 
    /// Runs after upgrading to the latest migration to allow seed data to be updated. 
    /// 
    /// </summary> 
    /// 
    /// <remarks> 
    /// Note that the database may already contain seed data when this method runs. This means that 
    ///    implementations of this method must check whether or not seed data is present and/or up-to-date 
    ///    and then only make changes if necessary and in a non-destructive way. The 
    ///    <see cref="M:System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate``1(System.Data.Entity.IDbSet{``0},``0[])"/> 
    ///    can be used to help with this, but for seeding large amounts of data it may be necessary to do less 
    ///    granular checks if performance is an issue. 
    ///    If the <see cref="T:System.Data.Entity.MigrateDatabaseToLatestVersion`2"/> database 
    ///    initializer is being used, then this method will be called each time that the initializer runs. 
    ///    If one of the <see cref="T:System.Data.Entity.DropCreateDatabaseAlways`1"/>, <see cref="T:System.Data.Entity.DropCreateDatabaseIfModelChanges`1"/>, 
    ///    or <see cref="T:System.Data.Entity.CreateDatabaseIfNotExists`1"/> initializers is being used, then this method will not be 
    ///    called and the Seed method defined in the initializer should be used instead. 
    /// 
    /// </remarks> 
    /// <param name="context">Context to be used for updating seed data. </param> 

Zasadniczo, nie masz innej opcji niż wdrożenie „dodać lub zaktualizować” logiki, ponieważ metoda Seed zostanie wykonany za każdym razem po inicjator służy .

Metoda rozszerzenie AddOrUpdate jest przydatna do tego, ale użyłem również to w niektórych przypadkach:

  if (!context.Entities.Any()) 
      { 
       // Seed 
      } 
+1

Yup ... mam zamiar iść dalej i usunąć moją połowiczną pisemną odpowiedź, ponieważ twój przykładowy kod był dokładnie tym, o czym pisałem:) ... +1 –

+2

Głosowanie odrzucone, ponieważ całkowicie błędne jest stwierdzenie, że Metoda seed nie zostanie wykonana, jeśli nie ma oczekujących migracji. – Colin

+0

@Colin Masz rację. Mam to w moim kodzie "if (migrator.GetPendingMigrations(). Any())" przed wykonaniem "migrator.Update()". Aktualizuję moją odpowiedź. Dziękuję za to. –

4

Od tej strony: Database initializer and Migrations Seed methods:

Sposób Seed na klasy tras Configuration zawsze, gdy wykonywana jest komenda PowerShell PowerShell. Jeśli inicjator migracji nie zostanie użyty , metoda Migrations Seed nie zostanie wykonana po uruchomieniu aplikacji .

Tak, myślę, że nie masz wiele opcji tutaj, metoda migracji Seed zawsze zostanie wywołana po uruchomieniu polecenia Update-Database. Kopałem, jeśli istnieje parametr tego polecenia, który pozwala określić, aby nie uruchamiać metody Seed, ale jestem fraid, jeszcze nie istnieje. Są to wszystkie parametry można używać (można znaleźć więcej informacji w tej link):

Update-Database [-SourceMigration <String>] [-TargetMigration <String>] [-Script] [-Force] 
    [-ProjectName <String>] [-StartUpProjectName <String>] [-ConfigurationTypeName <String>] 
    [-ConnectionStringName <String>] [-AppDomainBaseDirectory <String>] [<CommonParameters>] 

Update-Database [-SourceMigration <String>] [-TargetMigration <String>] [-Script] [-Force] 
    [-ProjectName <String>] [-StartUpProjectName <String>] [-ConfigurationTypeName <String>] 
    -ConnectionString <String> -ConnectionProviderName <String> 
    [-AppDomainBaseDirectory <String>] [<CommonParameters>] 

Jeśli wykonanie skryptu SQL do wstawiania danych w metodzie Seed, można użyć warunku booleam uniknąć włóż ponownie te same pola po raz pierwszy.

Jako aditional informacji, prośba w mieć parametr, aby uniknąć wykonać metodę Seed po uruchomieniu komendy Update-Database już istnieje w tym site, który jest wykorzystywany przez zespół EF zebranie sugestii społeczności.

1

Przeniosłem wszystkie moje instrukcje początkowe na osobne metody, które można łatwo skomentować przed uruchomieniem "bazy danych aktualizacji".

protected override void Seed(Tpsc.EDI.EDIContext context) 
{ 
    try 
    { 
     //EDI.Seed.DoSeed(context); 
    } 
    catch (DbEntityValidationException e) 
    { 
     ... 
    } 
} 
0

Jeśli masz skrypty sql wstawić dane i chcesz zapobiec przyszłym wstawki, nie Możesz Użytkownik A sql scalić aby uniknąć duplikatów.Wstaw wszystkie dane znajdujące się w tabeli tymczasowej o takiej samej strukturze docelowej tabeli, a następnie użyj scalenia, aby zdecydować, kiedy wstawiać rekordy. Jeśli pasują, to dlatego, że wstawiłeś jeden raz.

Podobno S jest tabela temp ze wszystkimi swoimi danymi i T końcowej tabeli

MERGE Target AS T 
USING Source AS S 
ON (T.EmployeeID = S.EmployeeID AND T.EmployeeName LIKE 'S%' 
    AND S.EmployeeName LIKE 'S%') 
WHEN NOT MATCHED BY TARGET 
    THEN INSERT(EmployeeID, EmployeeName) VALUES(S.EmployeeID, S.EmployeeName) 
WHEN MATCHED 
    THEN UPDATE SET T.EmployeeName = S.EmployeeName 
WHEN NOT MATCHED BY SOURCE 
    THEN DELETE 

Aby uzyskać więcej odniesień używają https://technet.microsoft.com/en-us/library/bb522522(v=sql.105).aspx

0

I zazwyczaj użyć polecenia update-database -sc następnie uruchomić skrypt wygenerowany zaktualizować bazę danych ręcznie. Na początku nie czułem się komfortowo, ale teraz chciałbym zobaczyć, co się stanie z moją bazą danych, zanim będzie za późno.

Powiązane problemy