【ASP.NET Core入門記】データファーストでScaffoldする【MVC】

# 【ASP.NET Core入門記】データファーストでScaffoldする【MVC】

## 目的
EntityFrameworkCoreのScaffold機能を利用して、データベースの内容から
データを操作する__CRUD Webアプリケーションを自動生成__します。

## Scaffoldって？
「Scaffold」とは「足場」という意味で、データベースの基本操作に
必要な機能の骨組みを自動生成する機能のことを指します。

データベースの基本操作（CRUD）とは、

* Create（行の作成⇒INSERT）
* Read（行の参照⇒SELECT）
* Update（行の更新⇒UPDATE）
* Delete（行の削除⇒DELETE）

のことを指し、DB上のエンティティに対する操作を行うWebアプリケーションを、
自動的に生成することが出来ます。

## 環境
* Windows10 Anniversary Update
* Microsoft SqlServer 2014
* Microsoft VisualStudio2015

## 手順

### データベースの作成

1. SqlServerで適当なデータベースを作成します。
    ここでは、データベース名を「ScaffoldDB」とします。

    ~~~Sql
    CREATE DATABASE ScaffoldDB
    ~~~

2. 作成したDBにテーブルを追加します。
    ここでは、「社員」を管理するpersonテーブルと、
    「所属」を管理する「department」テーブルの２つを作成します。
    SQLの細かい内容についてはここでは触れません。

    ~~~Sql
    CREATE TABLE person (
        id int IDENTITY(1,1) NOT NULL,
        name VARCHAR(50) NOT NULL,
        age int NOT NULL,
        dep_id int NOT NULL
        CONSTRAINT PK_Person1 PRIMARY KEY CLUSTERED
        (
            id ASC
        )
    )
    ~~~

    ~~~Sql
    CREATE TABLE department (
        id int IDENTITY(1,1) NOT NULL,
        name VARCHAR(50) NOT NULL,
        CONSTRAINT PK_Department PRIMARY KEY CLUSTERED
        (
            id ASC
        )
    )
    ~~~

3. 作成した２つのテーブルにリレーションを結びます。
    personテーブルのdep_idから、depertmentテーブルのidを参照できるようにします。

    ~~~Sql
    ALTER TABLE person    
    ADD CONSTRAINT FK_Person_Department FOREIGN KEY (dep_id)     
        REFERENCES Department (id);
    ~~~

4. SqlServer Management Studioからデータベースダイアグラムを確認し、
    ２つのテーブルが正しいリレーションで結ばれていることを確認します。
    ![a.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/f4e92f1d-105b-0b00-0bbf-953385821f71.png)

5. 作成したテーブルにテストデータを挿入します。

    ~~~Sql
    INSERT INTO department VALUES('営業部');
    INSERT INTO department VALUES('開発部');

    INSERT INTO person VALUES('yamada',30,2);
    INSERT INTO person VALUES('yoshida',35,1);
    ~~~

### プロジェクトの作成
プロジェクトの作成には、コマンドラインから作成するパターンと、
VisualStudio2015からウィザードを用いて作成するパターンの２つがありますが、
今回はVisualStudio2015からウィザードを用いて作成します。

コマンドラインを用いて作成するパターンは、こちらの記事を参考にして下さい。

【ASP.NET Core】PowerShellからScaffoldする【MVC】
<http://qiita.com/logikuma/items/95af749cd387cb71a4a0>

1. VisualStudio2015を起動し、「ファイル」＞「新規」＞「新しいプロジェクト」から、
    「ASP.NET Core Web Application (.NET Core)」を選択します。
    名前は「ScaffoldTest」とします。
    ![b.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/a6a74dec-9593-6354-11c2-c9fca8f1ee9f.png)

2. テンプレート選択画面となるので、Webアプリケーションを選択し、
    「認証の変更」ボタンから「個別のユーザーアカウント」を選択します。
    これにより、ローカルデータベースへのアクセスに必要なプロジェクト情報を、
    VisualStudioが自動的に作成してくれます。
    ![c.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/af4dab73-0962-a670-be09-77ca975705e0.png)

### モデルの自動生成
モデルの作成には、Windows Powershellからdotnet efコマンドを発行します。

1. ソリューションエクスプローラ上のプロジェクトルート（ScaffoldTest）をクリックし、
    下部ウィンドウ内にある「プロパティ」からフォルダパスを取得します。

2. 取得したフォルダパスをエクスプローラで開き、エクスプローラ上から
    Powershellを起動します。
    ![d.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/712ecace-a9f8-791e-13e5-a20403f74666.png)

    エクスプローラのディレクトリ表示部分に「powershell」と入力すると、
    そのディレクトリ上でPowershellが起動されます。

3. Powershellから下記コマンドを実行します。

    ~~~
    dotnet ef dbcontext scaffold "Server=データベースサーバ名;Database=ScaffoldDB;Trusted_Connection=True" Microsoft.EntityFrameworkCore.SqlServer -o Models
    ~~~

    EntityFrameworkのscaffold機能を用いて、DIクラスとなるdbContextを自動的に生成し、
    そのデータベース内にあるテーブルをモデルクラスとしてC#のコードに自動生成します。
    新しく生成されたModelsパッケージの中を見てみると、Person.cs、Depatment.cs、
    ScaffoldDBContext.csが生成されています。

### コントローラ・ビューの自動生成
作成したモデルを用いて、コントローラ・ビューも自動生成することが出来ます。
これにより、データのみ作成するだけでCRUDアプリケーションを作成することが出来ます。

1. ソリューションエクスプローラからControllersを右クリックし、
    「追加」＞「新規スキャフォールディングアイテム」を選択します。
    ![e.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/fbe645ca-b1d0-1d2b-68d6-0b61a77f4b9c.png)

2. 「MVC Controller with views, using Entity Framework」を選択し、
    追加ボタンをクリックします。

3. コントローラの追加ダイアログが表示されるので、モデルクラスにPerson、
    データコンテキストクラスにScaffoldDBContextを指定、
    コントローラ名は複数形にする決まりがあるので、PeopleControllerにして追加をクリックします。
    ![f.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/7e07bc2e-9817-f264-13fd-422b67b58efa.png)

4. Startup.csを修正します。Startup.cs > ConfigureServiceメソッド内に一行追加します。

    ~~~csharp
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddApplicationInsightsTelemetry(Configuration);

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();
        
        //DBContextを読み込む
        services.AddDbContext<ScaffoldDBContext>(); // この行を追加

        services.AddMvc();

        // Add application services.
        services.AddTransient<IEmailSender, AuthMessageSender>();
        services.AddTransient<ISmsSender, AuthMessageSender>();
    }
    ~~~

### アプリケーションの実行
1. アプリケーションを実行します。
    上部メニューからIIS Expressを選択し、IIS上でWebアプリケーションを実行します。

2. ブラウザが起動したら、アドレスバーに/Peopleを追記し、移動します。
    ![g.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/95ad8d12-1c72-a36c-4a2d-7471c0b2cfaa.png)

    すると、先程入力したデータが一覧で表示されます。

### CRUD操作の確認
#### Create（生成）の確認
CreateNew と書かれたリンクをクリックし、情報を入力します。
情報入力の際、データベース内で作成した関連により、DepIdがコンボボックスで表示されます。
Int型であるAgeは数値入力のみが許可され、エラーが発生しないようになっています。
![h.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/ef1d0ef7-16ef-ad10-dcfb-7cf03b57184b.png)

Createをクリックすると、データが作成されます。
![i.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/ff1c3417-c3dc-0fa4-288b-000f782b854c.png)

#### Read（参照）の確認
Detailsをクリックします。
![j.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/cea4f71f-417d-2dd2-b4c6-c572fd0187db.png)

Personテーブルの各行詳細が表示されます。
#### Update（更新）の確認
Editをクリックします。
![k.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/58450894-6e39-0f3f-efea-a66fb83dcf90.png)

各行を編集し、Saveをクリックすると、データが更新されます。
![l.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/a66fc40d-71e6-638a-3e91-f7276a68eafe.png)

#### Delete（削除）の確認
Deleteをクリックします。
![m.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/56bb231a-492a-3c54-bbf0-55ca743e2462.png)

確認画面が表示され、Deleteをクリックすると、データが削除されます。
![n.PNG](https://qiita-image-store.s3.amazonaws.com/0/131683/d4af89ae-cd1e-951a-9819-7a5489eada83.png)

### 感想
.NET Core すごい！

Ruby on Rails、Play Frameworkなど、他にもScaffold機能を利用できるフレームワークは
多くありますが、.NET Coreは手軽にサクサク生成できるので、非常に楽でした。

複雑なビジネスロジックや、複雑なSQLを発行しなければいけないシステムは
星の数ほどあると思いますが、ベーシックなWeb-CRUDアプリケーションであれば、
一から手で書いていくよりもよっぽど効率よく書けるように感じます。

ASP.NET Coreは他にもたくさん優れた点がありますので、
これからもっと学習して、使いこなしていきたいと思いました。