Yeoman generator-aspnetとEintity Framework 7で簡単なアプリケーションを作る

情報源: ASP.NET 5 with SQLite and Entity Framework 7 | Software Engineering

上を参考にVisual Studio 2015は使わずに、YeomanとVisual Studio Code 8.0を使って簡単なアプリケーション改造をしたいと思います。データベースとしてはSqlite 3を使って、ORマッパとしてはEF7を使います。

作業の環境ですが、ASP.NET 5は1.0.0-beta7のCoreClr、OSはWindows 10 Pro(x64)、コードの編集はVisual Studio Code v0.80を使用しました。

まずはgenerator-aspnetを使って、ASP.NET 5のWebアプリケーションのひな型を作ります。

> yo aspnet

     _-----_
    |       |    .--------------------------.
    |--(o)--|    |      Welcome to the      |
   {{EJS1-3}}_ )    |        generator!        |
    /___A___\    '--------------------------'
     |  ~  |
   __'.___.'__
 ´   {{EJS1-4}}

? What type of application do you want to create?
  Empty Application
  Console Application
  Web Application
> Web Application Basic [without Membership and Authorization]
  Web API Application
  Nancy ASP.NET Application
  Class Library
  Unit test project

? What's the name of your ASP.NET application? Sqlite

Web Application [without Membership and Authorization]を選んで、プロジェクト名前はSqlightとします。

VS Codeでこのプロジェクトを開いて、project.jsonに変更を加えます。

まず、dependenciesにEF7への参照を追加します。

  "dependencies": {
    "Microsoft.AspNet.Diagnostics": "1.0.0-beta7",
    "Microsoft.AspNet.Mvc": "6.0.0-beta7",
    "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-beta7",
    "Microsoft.AspNet.Server.IIS": "1.0.0-beta7",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-beta7",
    "Microsoft.AspNet.Server.WebListener": "1.0.0-beta7",
    "Microsoft.AspNet.StaticFiles": "1.0.0-beta7",
    "Microsoft.AspNet.Tooling.Razor": "1.0.0-beta7",
    "Microsoft.Framework.Configuration.Json": "1.0.0-beta7",
    "Microsoft.Framework.Logging": "1.0.0-beta7",
    "Microsoft.Framework.Logging.Debug" : "1.0.0-beta7",
    "Microsoft.Framework.Logging.Console": "1.0.0-beta7",
    "EntityFramework.Core" : "7.0.0-beta7",
    "EntityFramework.Commands" : "7.0.0-beta7",
    "EntityFramework.Sqlite": "7.0.0-beta7"
  },

CommandsにEntity Frameworkのコマンドを追加します

"commands": {
    "kestrel": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --config hosting.ini",
    "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --config hosting.ini",
    "ef": "EntityFramework.Commands"
  },

以上一度保存し、dnu restoreで一度リストアしてください。

次にモデルを作成します。

プロジェクトディレクトリにModelsディレクトリを追加します。作成したディレクトリに移動して、スキャフォールディングでクラスを追加します。

> mkdir Models
> cd Models
> yo aspnet:Class DataEventRecord
You called the aspnet subgenerator with the arg Sqlite.DataEventRecord
DataEventRecord.cs created.
   create DataEventRecord.cs
> ls
Sqlite.DataEventRecord.cs

aspnet:Class でクラスのひな型とファイルを作成します。

作成したひな型を以下のように変更します。

using System;
using Microsoft.Data.Entity;

namespace SqLite.Models
{
    public class DataEventRecord
    {
        public int Id {get; set;}
        public string Name {get; set;}
        public string Description {get; set;}
        public DateTime TimeStamp {get; set;}
    }
    
    public class DataEventRecodContext : DbContext
    {
        public DbSet<DataEventRecord> DataEventRecords {get; set;}
        
        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Entity<DataEventRecord>().Key(m => m.Id);
            base.OnModelCreating(builder);
        }
    }
}

次にDIでモデルと登録します。Startup.csのConfigureServicesメソッドを修正します。

using Microsoft.Data.Entity;
using SqLite.Models;
...
        public void ConfigureServices(IServiceCollection services)
        {
            var connection = "Data Source=C:\\Users\\ishisaka\\src\\aspnet\\SqLite\\dataeventrecords.sqlite";
            
            services.AddEntityFramework()
                .AddSqlite()
                .AddDbContext(options => options.UseSqlite(connection));
            // Add MVC services to the services container.
            services.AddMvc();           
        }

usingにMicrosoft.Data.EntityとSqLite.Modelsを追加し。6から10行目をConfigureServicesに追加します。

6行目はSqliteの接続文字列、8から10行目がEFの登録と接続設定です。

コンソールはproject.jsonがあるディレクトリに戻ります。

dnu buildコマンドで一度ビルドし、ここまでで単純なミスがない確認しておくとよいと思います。

次にEntity Framewrokのコマンドを使って、初回のデータベースのマイグレーションを行います。

> dnx ef migrations add SqliteMigrations
Using context 'DataEventRecodContext'.
Writing migration to 'C:\Users\ishisaka\src\aspnet\Sqlite\Migrations\20150913125329_SqliteMigrations.cs'.
Writing model snapshot to 'C:\Users\ishisaka\src\aspnet\Sqlite\Migrations\DataEventRecodContextModelSnapshot.cs'.
Done. To undo this action, use 'ef migrations remove'

Migrationsディレクトリが作成され、その中にマイグレーションのために必要な3つの.csファイルが作成されます。

Entity Framewrokのコマンドと先ほど作られたコードを使って、データベースファイルを作成し、データベースにテーブルを作成します。

> dnx ef database update
Using context 'DataEventRecodContext'.
Using database 'main' on server 'C:\Users\ishisaka\src\aspnet\SqLite\dataeventrecords.sqlite'.
Applying migration '20150913125329_SqliteMigrations'.
Done.

以上でEntity Frameworkで初回やるべきことは大体終わったので、実際にこのデータベースを使う法のコードを書いていきます。

まず、Conrollerを追加するので、コンソールではControllersに移動して、スキャフォールディングでコントローラクラスとそのファイルを追加します。

> cd Controllers
> yo aspnet:MvcController DataEventRecordController
You called the aspnet subgenerator with the arg DataEventRecordController
DataEventRecordController.cs created.
   create DataEventRecordController.cs

作成されたひな形をもとに以下のように修正します。

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Mvc;
using SqLite.Models;

namespace SqLite.Controllers
{
    public class DataEventRecordController : Controller
    {
        private DataEventRecodContext _context;
        
        public DataEventRecordController(DataEventRecodContext context)
        {
            _context = context;
        }
                
        // GET: /<controller>/
        public IActionResult Index()
        {
            return View(_context.DataEventRecords.ToList());
        }
        
        public IActionResult Create()
        {
            return View();
        }
        
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Create(DataEventRecord record)
        {
            if (ModelState.IsValid)
            {
                _context.DataEventRecords.Add(record);
                _context.SaveChanges();
                return RedirectToAction("Index");
            }
            
            return View(record);
        }
    }
}

次にViewを追加します。コンソールはプロジェクトのViewsディレクトリに移動して、DataEventRecordディレクトリを作成します。
作成したディレクトリに移動し、スキャフォールディングでViewの.cshtml(Razor)ファイルを作成します。データ一覧を表示するIndex.cshtmlと、入力画面のCreate.cshtmlを作成します。

> cd ..\Views
> mkdir DataEventRecord
> cd DataEventRecord
> yo aspnet:MvcView Index
You called the aspnet subgenerator with the arg Index
Index.cshtml created.
   create Index.cshtml
> yo aspnet:MvcView Create
You called the aspnet subgenerator with the arg Create
Create.cshtml created.
   create Create.cshtml

Index.cshtmlの内容を以下のように変更します。

@model IEnumerable<SqLite.Models.DataEventRecord>

@*
    For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
    ViewBag.Title = "Data Events";
}

<h2>Data Events</h2>


    @Html.ActionLink("Create New", "Create")


<table class="Table">
    <tr>
        <th>
            Id
        </th>
        <th>
            Name
        </th>
        <th>
            Description
        </th>
        <th>
            TimeStamp
        </th>
    </tr>
    
    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Id)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Description)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.TimeStamp)
            </td>
        </tr>
    }
</table>

Create.cshtmlも以下のように修正します。

@model SqLite.Models.DataEventRecord

@{
    ViewBag.Title = "Create Page";
}

<h2>New Event</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        @Html.ValidationSummary(true, "", new {@class = "text.danger"})
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new {@class = "control-label col-md-2"})
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new {htmlAttributes = new {@class = "form-control"}})
                @Html.ValidationMessageFor(model => model.Name, "", new {@class = "text-danger"})
            </div>
            @Html.LabelFor(model => model.Description, htmlAttributes: new {@class = "control-label col-md-2"})
            <div class="col-md-10">
                @Html.EditorFor(model => model.Description, new {htmlAttributes = new {@class = "form-control"}})
                @Html.ValidationMessageFor(model => model.Description, "", new {@class = "text-danger"})
            </div>     
            @Html.LabelFor(model => model.TimeStamp, htmlAttributes: new {@class = "control-label col-md-2"})
            <div class="col-md-10">
                @Html.EditorFor(model => model.TimeStamp, new {htmlAttributes = new {@class = "form-control"}})
                @Html.ValidationMessageFor(model => model.TimeStamp, "", new {@class = "text-danger"})
            </div>     
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

プロジェクトのトップに戻り、アプリケーションを実行します。

> dnx web
info    : [Microsoft.Net.Http.Server.WebListener] Start
info    : [Microsoft.Net.Http.Server.WebListener] Listening on prefix: http://localhost:5000/
Application started. Press Ctrl+C to shut down.

ブラウザでhttp://localhost:5000/DataEventRecordにアクセスします。

SnapCrab_Data Events - Sqlite - Google Chrome_2015-9-13_22-21-16_No-00

当然ですがデータはありませんが、表示されています。

Create Newをクリックしてデータを追加してみましょう。

SnapCrab_Create Page - Sqlite - Google Chrome_2015-9-13_22-24-39_No-00

データを追加すると結果が表示されます。

SnapCrab_Data Events - Sqlite - Google Chrome_2015-9-13_22-25-28_No-00

まとめ

標準のテンプレートに簡単な追加を加えた修正でしたが、Entity Framework 7のプロジェクトへの追加方法、Sqliteの使い方、Yeoman, generator-aspnetのスキャフォールディングを使った開発方法の流れがわかったのではないかと思います。

Windowsであれば確かにVSを使えば良いのですが、スキャフォールディング環境を用意してその中で開発していくやり方は、ASP.NETに限らず今のアプリケーション開発(特にWeb)の一つのスタイルなので、一度試して、感覚をつかんでおくのが良いと思います。いきなり慣れないRubyやNode.jsで始めるよりも慣れたC#で始めてみるのが良いと思います。

その他感想的ななことですが、VS Codeがcshtmlでのインテリセンスに対応してくれてなくて結構困りました。(日頃いかにVSに頼っているか…)

また、Yeomanのスキャフォールディングのコマンドですが、今回はコンソールから行っていますが、Atom + OmnisharpではOminisharpがインストール時にYeomanのプラグインもインストールするので、エディタ内からスキャフォールディングのコマンドを呼び出せるので便利かもしれません。(実際にはVS Codeにその機能は既にあるけど、私が使いこなせていないだけかもしれませんが。)

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください