Stosowanie migracji

Po dodaniu migracji należy je wdrożyć i zastosować do baz danych. Istnieją różne strategie tego działania, a niektóre są bardziej odpowiednie dla środowisk produkcyjnych, a inne dla cyklu projektowania.

Uwaga

Niezależnie od strategii wdrażania zawsze sprawdzaj wygenerowane migracje i przetestuj je przed zastosowaniem do produkcyjnej bazy danych. Migracja może spowodować usunięcie kolumny, gdy intencja miała ją zmienić lub może zakończyć się niepowodzeniem z różnych powodów, gdy zastosowano ją do bazy danych.

Skrypty SQL

Zalecanym sposobem wdrażania migracji do produkcyjnej bazy danych jest generowanie skryptów SQL. Zalety tej strategii obejmują następujące elementy:

  • Skrypty SQL można przeglądać pod kątem dokładności; Jest to ważne, ponieważ stosowanie zmian schematu w produkcyjnych bazach danych jest potencjalnie niebezpieczną operacją, która może obejmować utratę danych.
  • W niektórych przypadkach skrypty można dostosować do określonych potrzeb produkcyjnej bazy danych.
  • Skrypty SQL mogą być używane w połączeniu z technologią wdrażania, a nawet mogą być generowane w ramach procesu ciągłej integracji.
  • Skrypty SQL mogą być udostępniane administratorowi bazy danych i mogą być zarządzane i archiwizowane oddzielnie.

Podstawowy sposób użycia

Następujące polecenie generuje skrypt SQL z pustej bazy danych do najnowszej migracji:

dotnet ef migrations script

Z od (do implikowane)

Poniższy kod generuje skrypt SQL z danej migracji do najnowszej migracji.

dotnet ef migrations script AddNewTables

Z i do

Poniższe polecenie generuje skrypt SQL z określonej from migracji do określonej to migracji.

dotnet ef migrations script AddNewTables AddAuditTable

Możesz użyć elementu from nowszego to niż w celu wygenerowania skryptu wycofywania.

Ostrzeżenie

Zanotuj potencjalne scenariusze utraty danych.

Generowanie skryptu akceptuje następujące dwa argumenty, aby wskazać, który zakres migracji należy wygenerować:

  • Migracja z migracji powinna być ostatnią migracją zastosowaną do bazy danych przed uruchomieniem skryptu. Jeśli nie zastosowano żadnych migracji, określ 0 wartość (jest to ustawienie domyślne).
  • Migracja to ostatnia migracja, która zostanie zastosowana do bazy danych po uruchomieniu skryptu. Ta wartość domyślna to ostatnia migracja w projekcie.

Idempotentne skrypty SQL

Skrypty SQL wygenerowane powyżej można zastosować tylko w celu zmiany schematu z jednej migracji na inną; Użytkownik jest odpowiedzialny za odpowiednie zastosowanie skryptu i tylko do baz danych w prawidłowym stanie migracji. Program EF Core obsługuje również generowanie skryptów idempotentnych , które wewnętrznie sprawdzają, które migracje zostały już zastosowane (za pośrednictwem tabeli historii migracji) i stosują tylko brakujące. Jest to przydatne, jeśli nie wiesz dokładnie, jaka była ostatnia migracja zastosowana do bazy danych, lub jeśli wdrażasz w wielu bazach danych, które mogą znajdować się w innej migracji.

Następujące elementy generują migracje idempotentne:

dotnet ef migrations script --idempotent

Narzędzia wiersza polecenia

Narzędzia wiersza polecenia ef mogą służyć do stosowania migracji do bazy danych. Chociaż produktywne w przypadku lokalnego tworzenia i testowania migracji, takie podejście nie jest idealne do zarządzania produkcyjnymi bazami danych:

  • Polecenia SQL są stosowane bezpośrednio przez narzędzie bez możliwości sprawdzenia lub zmodyfikowania ich przez dewelopera. Może to być niebezpieczne w środowisku produkcyjnym.
  • Zestaw .NET SDK i narzędzie EF muszą być zainstalowane na serwerach produkcyjnych i wymagają kodu źródłowego projektu.

Uwaga

Każda migracja jest stosowana we własnej transakcji. Zobacz Problem z usługą GitHub #22616, aby zapoznać się z omówieniem możliwych przyszłych ulepszeń w tym obszarze.

Następujące aktualizacje bazy danych do najnowszej migracji:

dotnet ef database update

Następujące aktualizacje bazy danych do danej migracji:

dotnet ef database update AddNewTables

Należy pamiętać, że można go również użyć do wycofania do wcześniejszej migracji.

Ostrzeżenie

Zanotuj potencjalne scenariusze utraty danych.

Aby uzyskać więcej informacji na temat stosowania migracji za pomocą narzędzi wiersza polecenia, zobacz dokumentację narzędzi platformy EF Core.

Pakiety

Pakiety migracji to pliki wykonywalne z jednym plikiem, których można użyć do stosowania migracji do bazy danych. Dotyczą one niektórych niedociągnięć skryptu SQL i narzędzi wiersza polecenia:

  • Wykonywanie skryptów SQL wymaga dodatkowych narzędzi.
  • Obsługa transakcji i dalsze zachowanie tych narzędzi są niespójne i czasami nieoczekiwane. Może to pozostawić bazę danych w stanie niezdefiniowanym, jeśli wystąpi błąd podczas stosowania migracji.
  • Pakiety można wygenerować w ramach procesu ciągłej integracji i łatwo wykonać później w ramach procesu wdrażania.
  • Pakiety można wykonywać bez instalowania zestawu .NET SDK lub narzędzia EF (a nawet środowiska uruchomieniowego platformy .NET, gdy są one samodzielne) i nie wymagają kodu źródłowego projektu.

Następujące elementy generują pakiet:

dotnet ef migrations bundle

Następujące elementy generują samodzielny pakiet dla systemu Linux:

dotnet ef migrations bundle --self-contained -r linux-x64

Aby uzyskać więcej informacji na temat tworzenia pakietów, zobacz dokumentację narzędzi EF Core.

efbundle

Wynikowy plik wykonywalny jest domyślnie nazwany efbundle . Może służyć do aktualizowania bazy danych do najnowszej migracji. Jest to odpowiednik uruchamiania dotnet ef database update lub Update-Database.

Argumenty:

Argument opis
<MIGRATION> Migracja docelowa. Jeśli wartość "0", wszystkie migracje zostaną przywrócone. Domyślnie jest to ostatnia migracja.

Opcje:

Opcja Krótkie opis
--connection <CONNECTION> Parametry połączenia do bazy danych. Wartość domyślna to określona w elemecie AddDbContext lub OnConfiguring.
--verbose -v Pokaż pełne dane wyjściowe.
--no-color Nie koloruj danych wyjściowych.
--prefix-output Prefiks danych wyjściowych z poziomem.

Poniższy przykład dotyczy migracji do lokalnego wystąpienia programu SQL Server przy użyciu określonej nazwy użytkownika i hasła.

.\efbundle.exe --connection 'Data Source=(local)\MSSQLSERVER;Initial Catalog=Blogging;User ID=myUsername;Password=myPassword'

Ostrzeżenie

Nie zapomnij skopiować pliku appsettings.json obok pakietu. Pakiet opiera się na obecności pliku appsettings.json w katalogu wykonywania.

Przykład pakietu migracji

Pakiet wymaga, aby uwzględnić migracje. Są one tworzone przy użyciu zgodnie z dotnet ef migrations add opisem w temacie Tworzenie pierwszej migracji. Po zakończeniu migracji do wdrożenia utwórz pakiet przy użyciu narzędzia dotnet ef migrations bundle. Na przykład:

PS C:\local\AllTogetherNow\SixOh> dotnet ef migrations bundle
Build started...
Build succeeded.
Building bundle...
Done. Migrations Bundle: C:\local\AllTogetherNow\SixOh\efbundle.exe
PS C:\local\AllTogetherNow\SixOh>

Dane wyjściowe są plikiem wykonywalnym odpowiednim dla docelowego systemu operacyjnego. W moim przypadku jest to system Windows x64, więc otrzymuję porzucony efbundle.exe w moim folderze lokalnym. Uruchomienie tego pliku wykonywalnego powoduje zastosowanie zawartych w nim migracji:

PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
Applying migration '20210903083845_MyMigration'.
Done.
PS C:\local\AllTogetherNow\SixOh>

Podobnie jak w przypadku dotnet ef database update programu lub Update-Databasemigracje są stosowane do bazy danych tylko wtedy, gdy nie zostały już zastosowane. Na przykład uruchomienie tego samego pakietu nie powoduje niczego, ponieważ nie ma nowych migracji do zastosowania:

PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
No migrations were applied. The database is already up to date.
Done.
PS C:\local\AllTogetherNow\SixOh>

Jeśli jednak zmiany w modelu zostaną wprowadzone i zostaną wygenerowane kolejne migracje za pomocą dotnet ef migrations addpolecenia , można je połączyć w nowy plik wykonywalny gotowy do zastosowania. Na przykład:

PS C:\local\AllTogetherNow\SixOh> dotnet ef migrations add SecondMigration
Build started...
Build succeeded.
Done. To undo this action, use 'ef migrations remove'
PS C:\local\AllTogetherNow\SixOh> dotnet ef migrations add Number3
Build started...
Build succeeded.
Done. To undo this action, use 'ef migrations remove'
PS C:\local\AllTogetherNow\SixOh> dotnet ef migrations bundle --force
Build started...
Build succeeded.
Building bundle...
Done. Migrations Bundle: C:\local\AllTogetherNow\SixOh\efbundle.exe
PS C:\local\AllTogetherNow\SixOh>

Napiwek

Za --force pomocą opcji można zastąpić istniejący pakiet nowym pakietem.

Wykonanie tego nowego pakietu dotyczy tych dwóch nowych migracji do bazy danych:

PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
Applying migration '20210903084526_SecondMigration'.
Applying migration '20210903084538_Number3'.
Done.
PS C:\local\AllTogetherNow\SixOh>

Domyślnie pakiet używa parametry połączenia bazy danych z konfiguracji aplikacji. Można jednak zmigrować inną bazę danych, przekazując parametry połączenia w wierszu polecenia. Na przykład:

PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe --connection "Data Source=(LocalDb)\MSSQLLocalDB;Database=SixOhProduction"
Applying migration '20210903083845_MyMigration'.
Applying migration '20210903084526_SecondMigration'.
Applying migration '20210903084538_Number3'.
Done.
PS C:\local\AllTogetherNow\SixOh>

Uwaga

Tym razem wszystkie trzy migracje zostały zastosowane, ponieważ żadna z nich nie została jeszcze zastosowana do produkcyjnej bazy danych.


Stosowanie migracji w czasie wykonywania

Aplikacja może stosować migracje programowo, zazwyczaj podczas uruchamiania. Chociaż produktywne w przypadku lokalnego tworzenia i testowania migracji, takie podejście jest niewłaściwe w przypadku zarządzania produkcyjnymi bazami danych z następujących powodów:

  • Jeśli uruchomiono wiele wystąpień aplikacji, obie aplikacje mogą próbować zastosować migrację jednocześnie i zakończyć się niepowodzeniem (lub co gorsza, spowodować uszkodzenie danych).
  • Podobnie jeśli aplikacja uzyskuje dostęp do bazy danych podczas migrowania innej aplikacji, może to spowodować poważne problemy.
  • Aby zmodyfikować schemat bazy danych, aplikacja musi mieć podwyższony poziom dostępu. Zazwyczaj dobrym rozwiązaniem jest ograniczenie uprawnień bazy danych aplikacji w środowisku produkcyjnym.
  • W przypadku problemu ważne jest, aby móc wycofać zastosowaną migrację. Inne strategie zapewniają to łatwo i z pudełka.
  • Polecenia SQL są stosowane bezpośrednio przez program bez możliwości sprawdzenia lub zmodyfikowania ich przez dewelopera. Może to być niebezpieczne w środowisku produkcyjnym.

Aby programowo zastosować migracje, wywołaj metodę context.Database.Migrate(). Na przykład typowa aplikacja ASP.NET może wykonywać następujące czynności:

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    using (var scope = host.Services.CreateScope())
    {
        var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
        db.Database.Migrate();
    }

    host.Run();
}

Należy pamiętać, że Migrate() opiera się na IMigrator usłudze, która może być używana w bardziej zaawansowanych scenariuszach. Użyj polecenia myDbContext.GetInfrastructure().GetService<IMigrator>() , aby uzyskać do niego dostęp.

Ostrzeżenie

  • Przed zastosowaniem tego podejścia w środowisku produkcyjnym należy dokładnie rozważyć. Doświadczenie wykazało, że prostota tej strategii wdrażania jest przeważona nad utworzonymi problemami. Rozważ wygenerowanie skryptów SQL na podstawie migracji.
  • Nie dzwonij EnsureCreated() przed Migrate(). EnsureCreated() Pomija migracje w celu utworzenia schematu, co powoduje Migrate() niepowodzenie.