Entiry Framework のCode FIrst で Model を変更した後にする事

EF初心者のかじです。
Code First で作成した後にモデルを変更したらちょっとハマったのでメモ。

環境

現象

Code First で Model を以下のように変更しアプリケーションを実行しました。

変更前のモデル

public class Staff
{
    [Key]
    public long id{get;set;}
    public string name{get;set;}

}

変更後のモデル

public class Staff
{
    [Key]
    public long id{get;set;}

    [Required]
    public string name{get;set;}

}

するとInvalidOperationExceptionが発生しました。

The model backing the 'HogeContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

対応開始

エラーメッセージの通り、モデルを変更したらMigration しないとだめですよね。
しかし、Migration ってどうやるの?ということで上記詳細にもURLがある解説ページに沿って対応してみます。


EF 4.3 Code-Based Migrations Walkthrough - ADO.NET Blog - Site Home - MSDN Blogs

Initial Migration の作成

Migration 用のコマンドを入力するためVisual Studio からコンソールを立ち上げます。

ツール→ライブラリ パッケージ マネージャー→パッケージ マネージャー コンソール

んで、Enable-Migrations コマンドを入力します。

PM> Enable-Migrations
Checking if the context targets an existing database...
Detected database created with a database initializer. Scaffolded migration '201206222058355_InitialCreate' corresponding to existing database. To use an automatic migration instead, delete the Migrations folder and re-run Enable-Migrations specifying the -EnableAutomaticMigrations parameter.
Code First Migrations enabled for project Hoge.

すると、プロジェクト内に「Migrations」フォルダができます。
201206222058355_InitialCreate.cs ファイルができるので中身を見ると
変更を加える前のモデルをDBに作成させた時に実行されたクラスファイルができます。
私の場合、6/22にStaffテーブルを作成したので以下の内容でした。

using System;
using System.Data.Entity.Migrations;
    
public partial class InitialCreate : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.Staffs",
            c => new
                {
                    id = c.Long(nullable: false, identity: true),
                    name = c.String(),
                })
            .PrimaryKey(t => t.id);
        
    }
   
    public override void Down()
    {
        DropTable("dbo.Staffs");
    }
}

Migration の作成と反映

Staffモデルに必須入力の制約を追加するのでMigration名をAddStaffRequiredConstraintで作成します。パッケージマネージャーコンソールに「Add-Migration AddStaffRequiredConstraint」と入力します。

PM> Add-Migration AddStaffRequiredConstraint
Scaffolding migration 'AddStaffRequiredConstraint'.
The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration 201206281349583_AddStaffRequiredConstraint' again.

すると以下のMigrationが作成されました。

using System;
using System.Data.Entity.Migrations;
    
public partial class AddStaffRequiredConstraint : DbMigration
{
    public override void Up()
    {
        AlterColumn("dbo.Staffs", "name", c => c.String(nullable: false));
    }
        
    public override void Down()
    {
        AlterColumn("dbo.Staffs", "name", c => c.String());
    }
}

Migration をDBに反映するため「Update-Database」を入力します。

PM> Update-Database
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Applying code-based migrations: [201206281349583_AddStaffRequiredConstraint].
Applying code-based migration: 201206281349583_AddStaffRequiredConstraint.
Running Seed method.

DBの定義を見るとNot null 制約がついてます。
これでアプリケーションが動きます。

EF 4.3 Code-Based Migrations Walkthrough - ADO.NET Blog - Site Home - MSDN Blogs
を見ると特定バージョンへのMigration(ダウングレード含む)、実際に実行されるSQLを取得する方法もあるようです。(未検証)