マイグレーション

マイグレーション


マイグレーションを利用することで、データベースを削除することなく既存データをそのままにして、
最新のテーブルレイアウトに変更できる。
※ちなみに、イニシャライザーではデータベースを一旦削除→再作成している。


【マイグレーションの基本】

Entity Frameworkのマイグレーションは大きく分けて2つある。

①自動マイグレーション

 アプリケーション実行時に自動でモデルの変更を検出し、テーブルレイアウトを最新の状態に移行する。
 (あまりお勧めできない。DBに反映されるタイミングを自分で決められないし、自動化できる対象が限定される)

②コードベースマイグレーション

 パッケージマネージャーコンソールからコマンドを発行してマイグレーションを実行する。
 任意のタイミングでマイグレーションが出来るのでこちらの方が推奨。


【マイグレーションを有効化する】

パッケージマネージャーコンソールを表示し、Enable-Migrationsコマンドでマイグレーション機能を
有効にする。
41
-ContextTypeNameオプションで、コンテキストの型を指定する。ルート名前空間から指定しないとエラーになる。
成功すると、Migrationsフォルダが作成され、2つのファイルが自動で作成される。
(Configuration.vb, yyyymmdd*******_InitialCreate.vb)

Configuration.vb

マイグレーションの基本設定を定義したファイル
[Migrations\Configuration.vb]

・AutomaticMigrationsEnabledプロパティ
 True:自動マイグレーション、 False:手動
・ContextKeyプロパティ
 コンテキストの完全修飾名
 (パッケージマネージャーコンソールでEnable-Migrationsコマンドで指定したものが設定される)
・Seedメソッド
 マイグレーション時に初期データを投入するのに使用
・AddOrUpdateメソッド
 同一キーのデータが存在するかどうかでINSERTとUPDATEを選択して発行するメソッド。

Seedメソッドを有効にするには以下のコードをglobal.asax.vbに対して追加する必要がある。
[global.asax.vb]

MigrateDatabaseToLatestVersionクラスはDBを最新に移行した上で、データも最新状態に移行するためのイニシャライザー


yyyymmdd*******_InitialCreate.vb

マイグレーションファイル(マイグレーションのための処理を記述したファイル)
Enable-Migrationsコマンドを実行した時点でのデータベースオブジェクトの操作を表すコードが作成される。
(DBが未作成の場合、このファイルは作られない)
ファイル名にはタイムスタンプがつけられており、これによってマイグレーション実行の是非を判断する。

[Migrations\yyyymmdd*******_InitialCreate.vb]

・Upメソッド
 DBをバージョンアップ時に呼び出されるメソッド
・Downメソッド
 DBをバージョンダウン時に呼び出されるメソッド


【マイグレーションファイルを自動生成→実行】

マイグレーションファイルは手動で作成する必要はなく、エンティティに対して変更を加えて
自動作成することが出来る。
例えば、models\author.vbにAddressプロパティを追加したとする。

この状態で実行すると以下のようなエラーとなる。
42
そこでパッケージマネージャーコンソールからAdd-Migrationコマンドを実行する。
(Add-Migrationコマンドはモデルの変更を検出してマイグレーションファイルを自動生成するコマンド)
43
パラメータの AddAddressToAuthorsはマイグレーションファイルの名前を指定している。(何でもいい)
成功すると、Migrationsフォルダ配下に以下のマイグレーションファイルが作成される。
[yyyymmdd*******_AddAddressToAuthors.vb]

前回のマイグレーションからのエンティティの変更を自動で認識して、コードを自動生成してくれる。
そのまま実行してもいいし、必要に応じて修正を加えてもいい。
試しに以下の変更を加えてみる。 (Address列のデフォルト値を「不明」に設定)

以上、準備が完了したらパッケージマネージャーコンソールから
「Update-Database -Verbose」とコマンドを実行する。
Update-Databaseコマンドは未実行のマイグレーションを実行してDBを更新するコマンド。
-Verboseオプションはマイグレーションで実行されるSQLを表示する。(省略可)
 
[Authorsテーブル(マイグレーション前)]
44
arrow_down
[Authorsテーブル(マイグレーション後)]
46
既存データを残したまま、Address列が追加される
※デフォルト値を設定したが、なぜか文字化けされてしまった。


マイグレーションの履歴

 
実行済みのマイグレーション情報はDBの__MigrationHistoryテーブルで管理されている。
47
このテーブルにより未実行のマイグレーションを判定している。
そのためこのテーブルをむやみにいじると正しくマイグレーションできなくなる可能性がある。


【Update-Databaseコマンドの用法】

①DBを特定の状態に戻す

DBを過去のある時点まで戻したい場合は、-TargetMigrationオプションを使用する。
以下は、InitialCreate(マイグレーションを有効にした時に作成されたマイグレーション)までDBを
戻す場合のコマンド
PM> Update-Database -TargetMigration: InitialCreate
(内部的にはInitialCreate以降に実行されたマイグレーションのDownメソッドが実行されている)

②DBを空にする

全てのマイグレーションを無効にして、DBを空にするには、$InitialDatabase を指定する。
PM> Update-Database -TargetMigration: $InitialDatabase
→テーブル等全てDropされる。

③SQLスクリプトを取得する

マイグレーションのSQLスクリプトを取得する場合、-Scriptオプションを使用する。
Update-Database -Script -SourceMigration:$InitialDatabase -TargetMigration:AddAddressToAuthors
-SourceMigrationオプションで基点となるポイントを指定(省略時はDBの現在の状態)
-TargetMigrationオプションで移行の終点となるポイントを指定(省略時は最新のマイグレーション)
コマンドを実行するとsqlファイルが表示される。


【自動マイグレーション】

自動マイグレーションを利用するにはマイグレーションを有効にするEnable-Migrationsコマンドで
-EnableAutomaticMigrationオプションを指定するか、既に作成済みのConfigurationクラスの
AutomaticMigrationsEnabledプロパティをtrueにする。
 
自動マイグレーションを利用することにより、プログラムを実行するだけで自動でDBが更新され、既存データも保持される。
(Add-Migrationコマンドでマイグレーションファイルを作成して、Update-DatabaseコマンドでDBを更新する必要がなくなる。)
 
また、自動マイグレーションでデータロスを伴う変更(列の削除等)を行いたい場合(列追加を戻す場合とか)
AutomaticMigrationDataLossAllowedプロパティをTrueに設定する。

[Migrations\Configuration.vb]

AuthorエンティティからAddressプロパティを削除して実行
[Authorsテーブル(実行前)]
46
arrow_down
[Authorsテーブル(実行後)]
44
Address列が削除されているのが確認できる。