SkyoceanHome
Home
Privacy
ダウンロード
SkyShop
Updated Information
チュートリアルコード集
References
記事編集
日付
ジャンルのカテゴリ―名
名前を選択して下さい。
Contexts
Controllers
Databases
Htmls
JavaScripts
Models
MVCTutorials
Others
Styles
Views
タイトル
内容の要旨
<div style="color: rgb(76, 76, 76); font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;" data-pasted="true"><p style="margin-top: 0px; line-height: 25.2px;">データベースを削除してから作り直すと,DBに保存されている情報が全て削除されてしまいます. こういった事態を回避する方法として、データベースマイグレーションを行う方法があります。 マイグレーションとは、DBに保存されているデータを保持したまま、テーブルの作成やカラムの変更などを行うための機能です。</p></div><div style="color: rgb(76, 76, 76); font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><h2 style="margin: 0px 0px 15px; padding: 0px; font-weight: bold; color: rgb(62, 53, 48); font-size: 17.5px; border-bottom: 1px dashed rgb(153, 153, 153);">3.2. マイグレーションの準備<a href="https://densan-labs.net/tech/codefirst/migration.html#id3" title="このヘッドラインへのパーマリンク" style="text-decoration: none; color: rgb(255, 108, 0); visibility: hidden;"></a></h2><p style="margin-top: 0px; line-height: 25.2px;">まずは簡単なデータベースマイグレーションを行うことにしましょう. あらかじめ,次のようなProductクラスを作成しておきます。</p><div style="background: rgb(240, 240, 240);"><pre style="background-color: rgb(238, 238, 238); padding: 0.75em 1.5em; font-size: 12px; border: 1px solid rgb(221, 221, 221);"><span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">class</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">Product</span> { <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(144, 32, 0);">int</span> ProductId { <span style="color: rgb(0, 112, 32); font-weight: bold;">get</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">set</span>; } <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(144, 32, 0);">string</span> Name { <span style="color: rgb(0, 112, 32); font-weight: bold;">get</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">set</span>; } <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(144, 32, 0);">int</span> Price { <span style="color: rgb(0, 112, 32); font-weight: bold;">get</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">set</span>; } }</pre></div><p style="margin-top: 0px; line-height: 25.2px;">また、このProductクラスにアクセスするためのContextである、ShoppingContextも作っておきましょう。</p><div style="background: rgb(240, 240, 240);"><pre style="background-color: rgb(238, 238, 238); padding: 0.75em 1.5em; font-size: 12px; border: 1px solid rgb(221, 221, 221);"><span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">class</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">ShoppingContext</span> : DbContext { <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> DbSet<Product> Products { <span style="color: rgb(0, 112, 32); font-weight: bold;">get</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">set</span>; } }</pre></div><p style="margin-top: 0px; line-height: 25.2px;">次にデータベースマイグレーションの準備を行います. まず, メニューバーのツール,Library Package Manager内にある NuGetのPackage Manager Consoleを起動してください.</p><p style="margin-top: 0px; line-height: 25.2px;">その後,以下のコマンドを入力してマイグレーションの準備をします.</p><blockquote style="background-color: rgb(240, 240, 240); padding: 10px; border-width: 1px 1px 1px 8px; border-style: solid; border-color: rgb(187, 187, 187);">PM> Enable-Migrations</blockquote><div style="margin-bottom: 20px; margin-top: 5px; text-align: center;"><a href="https://densan-labs.net/_images/entity_pic013.JPG" style="text-decoration: none; color: rgb(255, 108, 0);"><img alt="../../_images/entity_pic013.JPG" src="blob:https://skyocean.bz/e53dc7d3-a13a-43b6-80ef-9a8cbe7953c1" style="width: 550px; height: 244px;" class="fr-fic fr-dii"></a><p style="margin-top: 0px; line-height: 25.2px; padding-top: 1em;">図: Package Manager Consoleを用いたMigrationの準備</p></div><p style="margin-top: 0px; line-height: 25.2px;">無事に成功すると,プロジェクト内にMigrationsというディレクトリと, 設定用のクラスファイルが自動的に作成されていると思います.</p><div style="margin-bottom: 20px; margin-top: 5px; text-align: center;"><a href="https://densan-labs.net/_images/migration01.png" style="text-decoration: none; color: rgb(255, 108, 0);"><img alt="../../_images/migration01.png" src="blob:https://skyocean.bz/da92c7d1-dc0f-4626-9421-4aa0c3859243" style="width: 345px; height: 297px;" class="fr-fic fr-dii"></a><p style="margin-top: 0px; line-height: 25.2px; padding-top: 1em;">図: 自動生成されたマイグレーション設定クラス</p></div><p style="margin-top: 0px; line-height: 25.2px;">これでマイグレーションのための準備が整いました。</p></div><div style="color: rgb(76, 76, 76); font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><h2 style="margin: 0px 0px 15px; padding: 0px; font-weight: bold; color: rgb(62, 53, 48); font-size: 17.5px; border-bottom: 1px dashed rgb(153, 153, 153);">3.3. テーブルの新規作成<a href="https://densan-labs.net/tech/codefirst/migration.html#id4" title="このヘッドラインへのパーマリンク" style="text-decoration: none; color: rgb(255, 108, 0); visibility: hidden;"></a></h2><p style="margin-top: 0px; line-height: 25.2px;">マイグレーションの機能を使って、Productsテーブルを生成しましょう。 EntityFrameworkには、Productクラスの中身を参照し、テーブル作成のためのクラスを自動生成してくれる機能が備わっています。 次のコマンドをPackage Manager Consoleに入力してください.</p><blockquote style="background-color: rgb(240, 240, 240); padding: 10px; border-width: 1px 1px 1px 8px; border-style: solid; border-color: rgb(187, 187, 187);">PM> Add-Migration InitialModels</blockquote><p style="margin-top: 0px; line-height: 25.2px;">InitialModelsの部分は、マイグレーションファイルのクラス名となります。できるだけ分かりやすい名前を付けましょう。</p><p style="margin-top: 0px; line-height: 25.2px;">もし、ソリューション内に複数プロジェクトが存在する場合は、ProjectName とStartUpProjectName を指定する必要があります。 例えば、プロジェクト名がCodeFirstMigrationの場合は、次のように指定します。</p><blockquote style="background-color: rgb(240, 240, 240); padding: 10px; border-width: 1px 1px 1px 8px; border-style: solid; border-color: rgb(187, 187, 187);">PM> Add-Migration InitialModels -ProjectName CodeFirstMigration -StartUpProjectName CodeFirstMigration</blockquote><p style="margin-top: 0px; line-height: 25.2px;">ProjectNameは、生成したいテーブルのDbContextを含んでいるプロジェクト名を指定します。 StartUpProjectNameには、App.config等でDBへのConnectionStringsの設定がされているプロジェクト名を指定します。</p><p style="margin-top: 0px; line-height: 25.2px;">Add-Migrationコマンドの発行に成功すると、Migrationsディレクトリ化に、作成日時 + _InitialModels.cs というファイルが生成されるはずです。 InitialModels.cs の中身は以下のようになります。</p><div style="background: rgb(240, 240, 240);"><pre style="background-color: rgb(238, 238, 238); padding: 0.75em 1.5em; font-size: 12px; border: 1px solid rgb(221, 221, 221);"><span style="color: rgb(0, 112, 32); font-weight: bold;">namespace</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">CodeFirstMigration.Migrations</span> { <span style="color: rgb(0, 112, 32); font-weight: bold;">using</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">System.Data.Entity.Migrations</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">partial</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">class</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">InitialModels</span> : DbMigration { <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">override</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">void</span> <span style="color: rgb(6, 40, 126);">Up</span>() { CreateTable( <span style="color: rgb(64, 112, 160);">"Products"</span>, c => <span style="color: rgb(0, 112, 32); font-weight: bold;">new</span> { ProductId = c.Int(nullable: <span style="color: rgb(0, 112, 32); font-weight: bold;">false</span>, identity: <span style="color: rgb(0, 112, 32); font-weight: bold;">true</span>), Name = c.String(), Price = c.Int(nullable: <span style="color: rgb(0, 112, 32); font-weight: bold;">false</span>), }) .PrimaryKey(t => t.ProductId); } <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">override</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">void</span> <span style="color: rgb(6, 40, 126);">Down</span>() { DropTable(<span style="color: rgb(64, 112, 160);">"Products"</span>); } } }</pre></div><p style="margin-top: 0px; line-height: 25.2px;">マイグレーションクラスには、UpとDownという二つの関数が存在します。 Upにはこれから変更したいDBへの変更を書きます。Downは反対に、変更を取り消したい場合に利用します。</p><p style="margin-top: 0px; line-height: 25.2px;">Up関数内にあるCreateTable関数は、第一引数にこれから生成するテーブルの名前を、第2引数にはテーブルの定義を記述します。 Entity Frameworkでは、基本的にPrimaryKeyは必須のため、PrimaryKey関数を使ってPrimaryKeyの指定も行っています。</p><p style="margin-top: 0px; line-height: 25.2px;">テーブル生成のためのクラスが作成されていることを確認したので、次はDBへマイグレートを行います。</p><p style="margin-top: 0px; line-height: 25.2px;">Package Manager Consoleから次のコマンドを入力します。</p><blockquote style="background-color: rgb(240, 240, 240); padding: 10px; border-width: 1px 1px 1px 8px; border-style: solid; border-color: rgb(187, 187, 187);">PM> Update-Database -Verbose</blockquote><p style="margin-top: 0px; line-height: 25.2px;">Verboseコマンドはつける必要はありませんが、この引数を指定することによって、どのようなSqlがDBに発行されているのかを確認することができます。</p><p style="margin-top: 0px; line-height: 25.2px;">複数プロジェクトがソリューション内に存在する場合は、Add-Migrationの時と同様に、ProjectNameとStartUpProjectNameの指定を行う必要があります。</p><blockquote style="background-color: rgb(240, 240, 240); padding: 10px; border-width: 1px 1px 1px 8px; border-style: solid; border-color: rgb(187, 187, 187);">PM> Update-Database -ProjectName CodeFirstMigration -StartUpProjectName CodeFirstMigration -Verbose</blockquote><p style="margin-top: 0px; line-height: 25.2px;">無事コマンド発行が成功すると、DBにProductsテーブルが生成されているはずです。 SQL SMSなどを使って確認してみましょう。</p><div style="margin-bottom: 20px; margin-top: 5px; text-align: center;"><a href="https://densan-labs.net/_images/migration02.png" style="text-decoration: none; color: rgb(255, 108, 0);"><img alt="../../_images/migration02.png" src="blob:https://skyocean.bz/0450905b-f6f6-49cb-b112-540d77cea6f3" style="width: 424px; height: 448px;" class="fr-fic fr-dii"></a><p style="margin-top: 0px; line-height: 25.2px; padding-top: 1em;">図: Productsテーブルの生成</p></div></div><div style="color: rgb(76, 76, 76); font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><h2 style="margin: 0px 0px 15px; padding: 0px; font-weight: bold; color: rgb(62, 53, 48); font-size: 17.5px; border-bottom: 1px dashed rgb(153, 153, 153);">3.4. テーブルの構成変更<a href="https://densan-labs.net/tech/codefirst/migration.html#id5" title="このヘッドラインへのパーマリンク" style="text-decoration: none; color: rgb(255, 108, 0); visibility: hidden;"></a></h2><p style="margin-top: 0px; line-height: 25.2px;">次に、前節で作成したProductクラスに、新しく在庫情報を管理するためのプロパティ、Stockを追加してみましょう。 DBマイグレーションの機能を使うと、データを保持したまま、テーブルの構成を簡単に変更できます。</p><p style="margin-top: 0px; line-height: 25.2px;">まずは、以下のようにProductクラスにStockプロパティを追加します。</p><div style="background: rgb(240, 240, 240);"><pre style="background-color: rgb(238, 238, 238); padding: 0.75em 1.5em; font-size: 12px; border: 1px solid rgb(221, 221, 221);"><span style="color: rgb(0, 112, 32); font-weight: bold;">namespace</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">CodeFirstMigration</span> { <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">class</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">Product</span> { <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(144, 32, 0);">int</span> ProductId { <span style="color: rgb(0, 112, 32); font-weight: bold;">get</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">set</span>; } <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(144, 32, 0);">string</span> Name { <span style="color: rgb(0, 112, 32); font-weight: bold;">get</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">set</span>; } <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(144, 32, 0);">int</span> Price { <span style="color: rgb(0, 112, 32); font-weight: bold;">get</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">set</span>; } <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(144, 32, 0);">int</span> Stock { <span style="color: rgb(0, 112, 32); font-weight: bold;">get</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">set</span>; } } }</pre></div><p style="margin-top: 0px; line-height: 25.2px;">次のコマンドをPackage Manager Consoleに入力してください.</p><blockquote style="background-color: rgb(240, 240, 240); padding: 10px; border-width: 1px 1px 1px 8px; border-style: solid; border-color: rgb(187, 187, 187);">PM> Add-Migration AddProductsStock</blockquote><p style="margin-top: 0px; line-height: 25.2px;">マイグレーションファイルの名前は何でも構いませんが、特に理由のない場合は、Add + 変更したいクラスの複数形の名前+変更したプロパティ名 としましょう. 実行後,以下のようなAddProductsStockクラスが自動生成されていると思います.</p><div style="background: rgb(240, 240, 240);"><pre style="background-color: rgb(238, 238, 238); padding: 0.75em 1.5em; font-size: 12px; border: 1px solid rgb(221, 221, 221);"><span style="color: rgb(0, 112, 32); font-weight: bold;">namespace</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">CodeFirstMigration.Migrations</span> { <span style="color: rgb(0, 112, 32); font-weight: bold;">using</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">System.Data.Entity.Migrations</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">partial</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">class</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">AddProductsStock</span> : DbMigration { <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">override</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">void</span> <span style="color: rgb(6, 40, 126);">Up</span>() { AddColumn(<span style="color: rgb(64, 112, 160);">"Products"</span>, <span style="color: rgb(64, 112, 160);">"Stock"</span>, c => c.Int(nullable: <span style="color: rgb(0, 112, 32); font-weight: bold;">false</span>)); } <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">override</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">void</span> <span style="color: rgb(6, 40, 126);">Down</span>() { DropColumn(<span style="color: rgb(64, 112, 160);">"Products"</span>, <span style="color: rgb(64, 112, 160);">"Stock"</span>); } } }</pre></div><p style="margin-top: 0px; line-height: 25.2px;">コードを見ればなんとなくわかるとは思いますが、Up関数内のAddColumn関数の第1引数は追加するテーブル名を、 第2引数には作成したいカラム名を、第3引数には作成したい型の情報を入力します。</p><p style="margin-top: 0px; line-height: 25.2px;">では,以下のコマンドを入力してマイグレーションを実行してみましょう.</p><blockquote style="background-color: rgb(240, 240, 240); padding: 10px; border-width: 1px 1px 1px 8px; border-style: solid; border-color: rgb(187, 187, 187);">PM> Update-Database -Verbose</blockquote><p style="margin-top: 0px; line-height: 25.2px;">SQL Management Studio等を用いてテーブルの定義、中身を確認してみましょう. 前回挿入したデータが消えていなければ成功です.</p><p style="margin-top: 0px; line-height: 25.2px;"><a href="https://densan-labs.net/tech/codefirst/chapter3.html#model-and-configuration" style="text-decoration: none; color: rgb(255, 108, 0);">モデルの変更とコンフィギュレーション</a> で説明したAnnotation機能を使えば、作成するカラムにさまざまな制約をつけることができます。</p><p style="margin-top: 0px; line-height: 25.2px;">例えば、Nameクラスを入力必須にし、MaxLengthを200文字としたい場合は、Productクラスを次のように変更します。</p><div style="background: rgb(240, 240, 240);"><pre style="background-color: rgb(238, 238, 238); padding: 0.75em 1.5em; font-size: 12px; border: 1px solid rgb(221, 221, 221);"><span style="color: rgb(0, 112, 32); font-weight: bold;">namespace</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">CodeFirstMigration</span> { <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">class</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">Product</span> { <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(144, 32, 0);">int</span> ProductId { <span style="color: rgb(0, 112, 32); font-weight: bold;">get</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">set</span>; } <span style="color: rgb(64, 112, 160);"> [Required]</span> <span style="color: rgb(64, 112, 160);"> [MaxLength(200)]</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(144, 32, 0);">string</span> Name { <span style="color: rgb(0, 112, 32); font-weight: bold;">get</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">set</span>; } <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(144, 32, 0);">int</span> Price { <span style="color: rgb(0, 112, 32); font-weight: bold;">get</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">set</span>; } <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(144, 32, 0);">int</span> Stock { <span style="color: rgb(0, 112, 32); font-weight: bold;">get</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">set</span>; } } }</pre></div><p style="margin-top: 0px; line-height: 25.2px;">この変更を適用するためのマイグレーションクラスを作成します。</p><blockquote style="background-color: rgb(240, 240, 240); padding: 10px; border-width: 1px 1px 1px 8px; border-style: solid; border-color: rgb(187, 187, 187);">PM> Add-Migration AddRequiredMaxLengthAttributesToName</blockquote><p style="margin-top: 0px; line-height: 25.2px;">作成されたマイグレーションクラスは次の通りです。</p><div style="background: rgb(240, 240, 240);"><pre style="background-color: rgb(238, 238, 238); padding: 0.75em 1.5em; font-size: 12px; border: 1px solid rgb(221, 221, 221);"><span style="color: rgb(0, 112, 32); font-weight: bold;">namespace</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">CodeFirstMigration.Migrations</span> { <span style="color: rgb(0, 112, 32); font-weight: bold;">using</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">System.Data.Entity.Migrations</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">partial</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">class</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">AddRequiredMaxLengthAttributesToName</span> : DbMigration { <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">override</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">void</span> <span style="color: rgb(6, 40, 126);">Up</span>() { AlterColumn(<span style="color: rgb(64, 112, 160);">"Products"</span>, <span style="color: rgb(64, 112, 160);">"Name"</span>, c => c.String(nullable: <span style="color: rgb(0, 112, 32); font-weight: bold;">false</span>, maxLength: <span style="color: rgb(64, 160, 112);">200</span>)); } <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">override</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">void</span> <span style="color: rgb(6, 40, 126);">Down</span>() { AlterColumn(<span style="color: rgb(64, 112, 160);">"Products"</span>, <span style="color: rgb(64, 112, 160);">"Name"</span>, c => c.String()); } } }</pre></div><p style="margin-top: 0px; line-height: 25.2px;">nullable falseで必須項目とし、maxLengthで文字数の指定をしています。 期待したマイグレーションクラスが作成されたら、Update-Database を発行し、DBの状態を確認してみましょう。 次のようなテーブルが作成されていたら成功です。</p><div style="margin-bottom: 20px; margin-top: 5px; text-align: center;"><img alt="../../_images/migration03.jpg" src="blob:https://skyocean.bz/86a47336-a9c8-47a3-a237-764e9e71afea" class="fr-fic fr-dii"><p style="margin-top: 0px; line-height: 25.2px; padding-top: 1em;">図: 構成変更後のテーブル定義</p></div></div><div style="color: rgb(76, 76, 76); font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><h2 style="margin: 0px 0px 15px; padding: 0px; font-weight: bold; color: rgb(62, 53, 48); font-size: 17.5px; border-bottom: 1px dashed rgb(153, 153, 153);">3.5. マイグレーションクラスの手動作成<a href="https://densan-labs.net/tech/codefirst/migration.html#id6" title="このヘッドラインへのパーマリンク" style="text-decoration: none; color: rgb(255, 108, 0); visibility: hidden;"></a></h2><p style="margin-top: 0px; line-height: 25.2px;">Productクラスの構成を変更し、Add-Migrationコマンドを発行することで、マイグレーションのためのクラスが自動生成されることを前節で確認しました。 しかし、一部機能を利用するためには、手動でマイグレーションクラスを作成する必要があります。</p><h3 style="margin: 0px 0px 15px; padding: 0px; font-weight: bold; color: rgb(62, 53, 48); font-size: 15.4px;">3.5.1. インデックスの作成<a href="https://densan-labs.net/tech/codefirst/migration.html#id7" title="このヘッドラインへのパーマリンク" style="text-decoration: none; color: rgb(255, 108, 0); visibility: hidden;"></a></h3><p style="margin-top: 0px; line-height: 25.2px;">インデックスを張りたい場合は、直接マイグレーションクラスを記述する必要があります。 まずは、Productテーブルをいじらず、次のコマンドを発行しましょう。</p><blockquote style="background-color: rgb(240, 240, 240); padding: 10px; border-width: 1px 1px 1px 8px; border-style: solid; border-color: rgb(187, 187, 187);">PM> Add-Migration AddNameIndexToProduct</blockquote><p style="margin-top: 0px; line-height: 25.2px;">空のマイグレーションが作成されたと思います。 作成されたクラスのUp関数にはIndexを張るための記述を、DownにはIndexを捨てるための記述を行います。 Indexを張るにはCreateIndex関数を、捨てる場合はDropIndex関数を利用します。</p><div style="background: rgb(240, 240, 240);"><pre style="background-color: rgb(238, 238, 238); padding: 0.75em 1.5em; font-size: 12px; border: 1px solid rgb(221, 221, 221);"><span style="color: rgb(0, 112, 32); font-weight: bold;">namespace</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">CodeFirstMigration.Migrations</span> { <span style="color: rgb(0, 112, 32); font-weight: bold;">using</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">System.Data.Entity.Migrations</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">partial</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">class</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">AddNameIndexToProduct</span> : DbMigration { <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">override</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">void</span> <span style="color: rgb(6, 40, 126);">Up</span>() { CreateIndex(<span style="color: rgb(64, 112, 160);">"Products"</span>, <span style="color: rgb(64, 112, 160);">"Name"</span>); } <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">override</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">void</span> <span style="color: rgb(6, 40, 126);">Down</span>() { DropIndex(<span style="color: rgb(64, 112, 160);">"Products"</span>, <span style="color: rgb(64, 112, 160);">"Name"</span>); } } }</pre></div><p style="margin-top: 0px; line-height: 25.2px;">作成したら、Update-Databaseを発行し、NameカラムにIndexが張られていることを確認しましょう。</p><div style="margin-bottom: 20px; margin-top: 5px; text-align: center;"><img alt="../../_images/migration04.png" src="blob:https://skyocean.bz/8c2636d5-48e8-46b6-8bfd-ec435a64f572" class="fr-fic fr-dii"><p style="margin-top: 0px; line-height: 25.2px; padding-top: 1em;">図: NameカラムへのIndexの追加</p></div><p style="margin-top: 0px; line-height: 25.2px;">複合Indexを張りたい場合は、次のように指定します。</p><div style="background: rgb(240, 240, 240);"><pre style="background-color: rgb(238, 238, 238); padding: 0.75em 1.5em; font-size: 12px; border: 1px solid rgb(221, 221, 221);">CreateIndex(<span style="color: rgb(64, 112, 160);">"Products"</span>, <span style="color: rgb(0, 112, 32); font-weight: bold;">new</span>[] { <span style="color: rgb(64, 112, 160);">"Name"</span>, <span style="color: rgb(64, 112, 160);">"ProductId"</span> })</pre></div><p style="margin-top: 0px; line-height: 25.2px;">また、UNIQUE指定をつけたい場合は、次のような記述を行います。</p><div style="background: rgb(240, 240, 240);"><pre style="background-color: rgb(238, 238, 238); padding: 0.75em 1.5em; font-size: 12px; border: 1px solid rgb(221, 221, 221);">CreateIndex(<span style="color: rgb(64, 112, 160);">"Products"</span>, <span style="color: rgb(64, 112, 160);">"Name"</span>, unique: <span style="color: rgb(0, 112, 32); font-weight: bold;">true</span>)</pre></div><h3 style="margin: 0px 0px 15px; padding: 0px; font-weight: bold; color: rgb(62, 53, 48); font-size: 15.4px;">3.5.2. Sql文の直接発行<a href="https://densan-labs.net/tech/codefirst/migration.html#sql" title="このヘッドラインへのパーマリンク" style="text-decoration: none; color: rgb(255, 108, 0); visibility: hidden;"></a></h3><p style="margin-top: 0px; line-height: 25.2px;">Entity FrameworkというORマッパーを利用していても、時には直接Sql文を発行したい場合もあるかとおもいます。 例えば、あらかじめ指定したデータをDBに投入しておきたい場合などは、マイグレーションクラス内に直接データInsert文を書いてしまう方法もあります。 直接Sqlを発行するには、Sql関数をUp,Down内に記述します。</p><div style="background: rgb(240, 240, 240);"><pre style="background-color: rgb(238, 238, 238); padding: 0.75em 1.5em; font-size: 12px; border: 1px solid rgb(221, 221, 221);"><span style="color: rgb(0, 112, 32); font-weight: bold;">namespace</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">CodeFirstMigration.Migrations</span> { <span style="color: rgb(0, 112, 32); font-weight: bold;">using</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">System.Data.Entity.Migrations</span>; <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">partial</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">class</span> <span style="color: rgb(14, 132, 181); font-weight: bold;">InsertRealProducts</span> : DbMigration { <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">override</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">void</span> <span style="color: rgb(6, 40, 126);">Up</span>() { Sql(<span style="color: rgb(64, 112, 160);">"INSERT INTO Products(Name, Price, Stock) VALUES(N'テスト商品', 100, 100)"</span>); } <span style="color: rgb(0, 112, 32); font-weight: bold;">public</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">override</span> <span style="color: rgb(0, 112, 32); font-weight: bold;">void</span> <span style="color: rgb(6, 40, 126);">Down</span>() { Sql(<span style="color: rgb(64, 112, 160);">"DELETE FROM Products WHERE Name = N'テスト商品'"</span>); } } }</pre></div></div><div style="color: rgb(76, 76, 76); font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><h2 style="margin: 0px 0px 15px; padding: 0px; font-weight: bold; color: rgb(62, 53, 48); font-size: 17.5px; border-bottom: 1px dashed rgb(153, 153, 153);">3.6. マイグレーションヒストリー<a href="https://densan-labs.net/tech/codefirst/migration.html#id8" title="このヘッドラインへのパーマリンク" style="text-decoration: none; color: rgb(255, 108, 0); visibility: hidden;"></a></h2><p style="margin-top: 0px; line-height: 25.2px;">EFは、いままでデータベースに対して、どのようなマイグレーションを行ってきたかという情報 を、システムテーブル内の_MigrationHistoryテーブル内で管理しています。</p><div style="margin-bottom: 20px; margin-top: 5px; text-align: center;"><a href="https://densan-labs.net/_images/migration_history.png" style="text-decoration: none; color: rgb(255, 108, 0);"><img alt="../../_images/migration_history.png" src="blob:https://skyocean.bz/29e0be28-58c8-4a9e-99e4-beab8bc83468" style="width: 500px; height: 472px;" class="fr-fic fr-dii"></a><p style="margin-top: 0px; line-height: 25.2px; padding-top: 1em;">図:マイグレーションヒストリー</p></div><p style="margin-top: 0px; line-height: 25.2px;">上図の場合は、DBに対してInitialCreateとAddProductsStockというマイグレーションが実行された ことを表しています。 このマイグレーションヒストリーがなんらかの原因で壊れてしまうと、うまくデータベースの アップデート及びマイグレーションができなくなってしまいます。 そうなってしまった場合、データベース自体を削除しなければならない事態となりますので、 十分に注意してください。</p></div><div style="color: rgb(76, 76, 76); font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><h2 style="margin: 0px 0px 15px; padding: 0px; font-weight: bold; color: rgb(62, 53, 48); font-size: 17.5px; border-bottom: 1px dashed rgb(153, 153, 153);">3.7. ダウングレード<a href="https://densan-labs.net/tech/codefirst/migration.html#id9" title="このヘッドラインへのパーマリンク" style="text-decoration: none; color: rgb(255, 108, 0); visibility: hidden;"></a></h2><p style="margin-top: 0px; line-height: 25.2px;">マイグレーションクラス内では、Up関数とDown関数という二つの関数が定義されていました。 Up関数内の処理はスキーマのアップグレード等に使いますが、Down関数内で定義されている処理は 反対にDB内のスキーマのダウングレードを行う時に使います。</p><p style="margin-top: 0px; line-height: 25.2px;">例えば、InitialCreateというマイグレーションとAddProductsStockというマイグレーション が既に適用されたDBが存在するとします。 ここで、一番最後に適用したAddProductsStockというマイグレーションを取り消したい場合、 つまり、一つ前のマイグレーション(InitialCreate)を行った状態に戻りたい場合は、次のような コマンドを実行します。</p><blockquote style="background-color: rgb(240, 240, 240); padding: 10px; border-width: 1px 1px 1px 8px; border-style: solid; border-color: rgb(187, 187, 187);">PM> Update-Database -TargetMigration:InitialCreate</blockquote><p style="margin-top: 0px; line-height: 25.2px;">ダウングレードした場合、いままで保存されていたデータの一部が消えてしまう場合が あるので、十分に注意して実行してください。</p></div><div style="color: rgb(76, 76, 76); font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><h2 style="margin: 0px 0px 15px; padding: 0px; font-weight: bold; color: rgb(62, 53, 48); font-size: 17.5px; border-bottom: 1px dashed rgb(153, 153, 153);">3.8. マイグレーションのタイムアウト<a href="https://densan-labs.net/tech/codefirst/migration.html#id10" title="このヘッドラインへのパーマリンク" style="text-decoration: none; color: rgb(255, 108, 0); visibility: hidden;"></a></h2><p style="margin-top: 0px; line-height: 25.2px;">Entity Framework 4.3.1の段階では、大量のデータがDBに存在している状態で Package Manager Console内からUpdate-Databaseを行うと、 途中でTimeoutという例外が発生し、マイグレーションを行えない場合があります。 この場合は面倒ではありますが、マイグレーション用のスクリプトを作成し、 自分でSQL Server等に対して命令を発行するしかありません。</p><p style="margin-top: 0px; line-height: 25.2px;">マイグレーション用スクリプトを作成するには、以下のコマンドを実行します。</p><blockquote style="background-color: rgb(240, 240, 240); padding: 10px; border-width: 1px 1px 1px 8px; border-style: solid; border-color: rgb(187, 187, 187);">PM> Update-Database -Script</blockquote><p style="margin-top: 0px; line-height: 25.2px;">コマンド発行後は、マイグレーションは行われず、マイグレーション用のスクリプトだけが生成されます。 このスクリプトをSQL Server等に対して手動で発行してください。</p></div><p data-f-id="pbf" style="text-align: center; font-size: 14px; margin-top: 30px; opacity: 0.65; font-family: sans-serif;">Powered by <a href="https://www.froala.com/wysiwyg-editor?pb=1" title="Froala Editor">Froala Editor</a></p>
コピーする
添付画像
画像を変更
Back to List
//検索文:Editor内でHTMLコードをコピーさせる