Entity Framework&MySQLでテーブルを作り直すときの注意

マイグレーションをリセットLink して元のデータをリストアする時、以下の条件に当てはまるエンティティがある場合注意が必要です。

  • ナビゲーションプロパティを持っている(→テーブルに外部キーが設定されている)状態でプロパティを追加した(特にshort, integer, long integer等整数型)
  • エンティティ定義しているソースコードの最後以外の行にプロパティを追加し、Add-Migrationした(ソースコード上のプロパティの順番が追加していった順になっていない)
問題はカラムの順番です。何が起こるかというと、プロパティ追加前、テーブルにはナビゲーションプロパティの外部キーを保存するためのカラムがあります。特にKey属性などを設定してない場合、参照先のIdカラムと同じinteger型になるでしょう。ここに新しいプロパティを追加すると、カラムの順番の最後に入ります。
Id integer primary key
Name varchar(30)
NavigationId integer (参照先のKeyカラムの型)
NewPropterty integer
次にマイグレーションを整理してテーブルを作り直すと、ナビゲーションプロパティのカラムが最後に入ります。
Id integer primary key
Name varchar(30)
NewPropterty integer
NavigationId integer (参照先のKeyカラムの型)

リストアは作り直した空テーブルへの実行となりますから、mysqldumpにはno-create-info(-t)オプションを付けることになると思います。これで出力されるファイルにはカラムの順番情報がありません。リストア先のテーブルもId, Name, NavigationId, NewPropertyの順番でカラムが並んでいる前提になってます。

このダンプファイルを使って作り直したテーブルにリストアするとNewPropertyとNavigationIdの値が入れ替わって保存されます。NewPropertyがvarcharなどNavigationIdと異なる型になっている場合はエラーなどになるでしょうが、同じ型の場合エラーなく保存されます。外部キー整合性のチェックはリストア時には行われないようです(やったらめちゃくちゃ重くなりそうだし)。結果ナビゲーションプロパティはでたらめなデータを参照します。

上記の内容がよく分からない、マイグレーションを重ねすぎて条件に合致するか分からない場合は、complete-insertオプションを付けてmysqldumpを実行した方が安全です。ダンプ・リストア共に劇的に遅くなりますが。

昔の記憶ですがPostgreSQL(8.1)もダンプはこういう仕様(オプション付けないとカラムの順番を保存しない)だったような。テーブル大きいとダンプ・リストアも高速化したいですからねぇ。

保険のためにデータベースのフルダンプ(テーブル作成SQL込み)を取ってなかったら爆死だったな…

— posted by mu at 09:47 am   commentComment [0]  pingTrackBack [0]

T: Y: ALL: Online:
ThemeSwitch
  • Basic
Created in 0.0089 sec.
prev
2015.7
next
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31