注意
今回の記事ではMigrationファイルを作成し反映する作業が多々あります。
説明は一度はしますが、反映に関するコマンドは面倒なので省略されることがあります。
そのため、まずは 次項にて 頻出コマンドを記載しておきます。
また、こういったしっかりした記事は初めて書きますので、何卒ご容赦いただければと思います。
頻出コマンド(PackageManagerConsole)
ツール(T)
-> Nugetパッケージマネージャ(N)
-> パッケージマネージャコンソール(O)
で入力するコマンドです。
Migration機能の有効化
プロジェクトにてMigrationの有効化を行うコマンドです。
一度有効化すれば問題ありません。
Enable-Migrations
なお、接続先変更等行った場合は再度このコマンドを叩く必要がありそうです。私の場合、有効化したあとに接続先を変更してMigrateしても変更前の接続先に反映されてしまいました。
再度有効化(厳密には再設定?)を行うには -Force
オプションをつければOKです。
Enable-Migrations -Force
Migrateファイルの作成
gitで commit -m "コメント"
のあとに push
を行うのと同様、
Migrateファイルに一度名前をつけて、その後反映させる必要があります。
Add-Migration MigrationName
データベースへの反映
そのままなので補足はありません。
Update-Database
参考サイト
EntityFrameworkについて
上記リンクはEntityFrameworkのタグです。
なお、本記事は上記リンクを知識定着のために書き直したものです。内容としては上記リンク先の内容と大差ありません。
列属性について
開発環境
Visual Studio 2017 Community
EntityFrameworkって?
ASP.netで使用できるDB関連のパッケージです。
LaravelやRoRでできる、スキャフォールド(Scaffold) や マイグレーション(Migration) ができます。
コードファースト(CodeFirst) という考えのもと、モデルを先に作ってしまえば、それに基づいてテーブルを作ってくれます。
なお、Seederもあります。
魅力的。
参照設定
Nugetから以下のパッケージを落としておきましょう。
- EntityFramework
- EntityFramework.ja
後者はお好みですが、メッセージが日本語になるので。
ツール(T)
-> Nugetパッケージマネージャ(N)
-> ソリューションのNugetパッケージの管理
で上記パッケージを検索してインストールするもよし、
ツール(T)
-> Nugetパッケージマネージャ(N)
-> パッケージマネージャコンソール(O)
で以下コマンドを叩いても可。
Install-Package EntityFramework
Install-Package EntityFramework.ja
プロジェクトの作成
今回はC#で作ってみました。WebAPIは対応せず以下の通り設定してます。
ソリューション名は EntityFrameworkTest ということで略して EFTest としてます。
特に設定もないのでそのまま作成しましょう。
- 新規プロジェクトの作成
Ctrl + Shift + N
で「新しいプロジェクト」画面を開きます。
※ もちろん ファイル(F)
-> 新規作成(N)
-> プロジェクト(P)
でも可能
続いて、表示された画面の左のツリーから
Visual C#
-> Web
中央のリストから
ASP.NET Webアプリケーション(.NET Framework)
を選択してソリューションを作成。
次の「 新しいASP. NET Webアプリケーション 」画面では
MVC を選択。画面下部のチェックボックスはMVCだけでよいかと。
作成完了したら、ソリューションエクスプローラーにつらつらとファイル群。
接続設定
参考にさせていただいたサイト様では中盤に設定の記載がありますが、地味につまづきポイントなのではじめに記載します。
なお、次に紹介する接続文字列の設定をしないと、デフォルトの長ったらしい名前でDBが作られてしまうのでご注意。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- 中略 -->
<!-- ↓を追加 -->
<connectionStrings>
<add name="EFTestDbContext" connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=EFTestDB" providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>
connectionStrings
要素が接続情報を管理しています。
今回重要視するのは
connectionString 属性。この値内にある Initial Catalog で設定している「EFTestDB」がDBの名前です。
クラスについて
DbContextクラス
こちらは、簡単に言うとModelとDBとの間を仲介するクラスです。CRUD処理時はこのクラスを介します。
このクラスはEntityFrameworkに用意されており、実装していきます。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace EFTest.Models
{
public class EFTestDbContext : System.Data.Entity.DbContext
{
}
}
このクラスの中身はModelと合わせて追加してくので、慌てない。
Migratio設定
続いてはMigrationの有効化が必要なんですね。プロジェクト単位で必要なようです。有効化はパッケージマネージャーで以下。
Enable-Migrations
少し待つと「完了しました」のメッセージ。
※このときのメッセージで、「コンテキストが既存のデータベースを対象にしているかをチェックしています」とあるので、DbContextクラスを作る前にやったらだめなのかな…?試してないです。
さて、完了後、設定ファイルが追加されるのがわかると思います。
Migrations/Configration.cs ができてます。私はこれだけでテンションが上ってました。今後、Migrate毎に Migrationsフォルダにファイルが追加されていくので乞うご期待。
namespace EFTest.Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
internal sealed class Configuration : DbMigrationsConfiguration<EFTest.Models.EFTestDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(EFTest.Models.EFTestDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data.
}
}
}
こちらがその設定ファイルです。 protected override void Seed
の文字があります。そうです、 Seeder でございます。
使うときに改めて。とりあえずこれにて設定は完了。
Migrate
第一回Migrateをしてみようと思います。
そのためには、モデルを作らないとですね。
では参考サイトに倣って都道府県テーブルを作りましょう。
Code | Name | Kana |
---|---|---|
01 | 北海道 | ホッカイドウ |
02 | 青森県 | アオモリケン |
... | ... | ... |
こんなやつ。
クラス名(テーブル名)は Prefectures としましょう。で、必要なフィールドをプロパティとして宣言。ここでValidationの条件等も設定できますが割愛。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace EFTest.Models
{
public class Prefecture
{
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public string Kana { get; set; }
}
}
IDは設定しておかないと、怒られますので追加します。ちなみに、デフォルトだとIDって名前じゃないと主キーとして認識されないようです。「この名前の列がいい!!」って言う人用に、設定もできますので後述。
続いて、DbContextも修正します。
モデルを追加したらそのDbSetも設定して上げる必要があるんですね。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace EFTest.Models
{
public class EFTestDbContext : DbContext
{
public DbSet<Prefecture> Prefecture { get; set; }
}
}
laravelなどを使ったことがある方は何となく分かるかもしれませんが、Migrateには名前を設定して上げる必要があります。
DbSetまで書けたら、PackageManagerConsoleで次のコマンドを叩いてMigrationに名称をつけてあげる必要があります。
Add-Migration CreatePrefecture
問題なければ、そのまま完了。
黄色い背景文字で注意書きもありますので見ておいてくださいまし。
完了すると MigrationディレクトリにMigrationファイルが作成されています。
namespace EFTest.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class CreatePrefecture : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.Prefectures",
c => new
{
Id = c.Int(nullable: false, identity: true),
Code = c.String(),
Name = c.String(),
Kana = c.String(),
})
.PrimaryKey(t => t.Id);
}
public override void Down()
{
DropTable("dbo.Prefectures");
}
}
}
Migration経験者だと タイムスタンプ + Migration名称 のファイル名に馴染みがあるかもしれませんね。
Update Database
Migrationファイルを作成しただけではDBに反映はされないので、PackageManagerConsoleで次のコマンドでを叩く必要があります。
Update-Database
これで、 web.config
に記載した名称のDB及び、Migrationファイル通りのテーブルが作られます。
(こらむ) Migrationのロールバック
Migrationがあるのであれば、間違えたときのロールバックもあるはず。あってほしいですよね。
無論あります。
まず、Migrationの状況を確認しましょう。
Migrations ディレクトリの中にあるファイルでもMigrationの状況はわかりますが、
Get-Migrations
でも確認できます。
今回は一つしか作っていないので戻すも何もありませんが、戻すMigrationを決めたら以下コマンドで戻します。今回は例としてInitialというバージョンに戻すことを想定します。
Update-Database -TargetMigration Initial
以上、Migrationの反映方法から戻し方、DBの設定方法などでした。
列属性、テーブル属性の変更について
続いては、プラスαの情報として属性についてお伝えします。
アノテーションを用いることで、例えば型や長さ、NotNullなどが設定できます
属性(Table)
まずはテーブルの属性変更。テーブルの属性って言っても主に変えることがありそうなのはテーブル名ですよね。
using System.ComponentModel.DataAnnotations.Schema;
namespace EFTest.Models
{
[Table("Hoge", Schema = "fuga")]
public class Prefecture
{
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public string Kana { get; set; }
}
}
こうすることで、テーブル名は dbo.Prefectures
から fuga.Hoge
となります。
なお、Schemaは指定しない場合は変更ありません。
属性(Column)
今回はこちらをご参照ください。
また折を見て私もまとめます。
1 : N, N : 1, N : N
Entity Frameworkでは(でも?)ありがちな多対多は実装できます。
例として下図のようなものを実装します。
(若干列の位置が違いますごめんなさい)
モデルの実装及びControllerでの呼び出し方法については下記Githubにて公開しますのでご参照ください。
Github EntityFrameworkSample
最後に
Qiitaにてしっかり書くのは初めてなので皆さんが毎回どれだけ大変な思いをされているか思い知りました。。
今後は、もっと視点を広く持ってわかりやすい共有記事や備忘録を書きますのでよろしくお願いいたします。