読者です 読者をやめる 読者になる 読者になる

1.21 jigowatts

Great Scott!

ASP.NET MVCはじめました~データベースより値を取得し一覧表示する

概要

環境

Visual Studio 2010
ASP.NET MVC2
SQLServer2008 R2

今回の要件は

  1. データベースより値を取得
  2. ブラウザに一覧表示

として、サンプルコードを書いてみました。

データベースの準備

テーブルの作成
CREATE TABLE [dbo].[Peple](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[Name] [nvarchar](20) NULL,
	[Address] [nvarchar](50) NULL,
	[PhoneNumber] [nvarchar](15) NULL,
	[UpdatedBy] [nvarchar](20) NULL,
	[UpdateDate] [datetime] NULL,
 CONSTRAINT [PK_Peple] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

実装

Entity Data Modelの用意

データベース周りはEntity Frameworkを使用します。
Models配下にEntity FrameworkでデータベースファーストによりEntity Data Modelを作成します。これがドメインモデルなのかな??
Pepleテーブルに対しエンティティ名はPerson、エンティティセット名はPepleにしました。

コントローラーの用意

MVCのC(Controller)を作成します。
コントローラーはスマートに保つため(テストをしなくていいように)仕事はサービス層へ丸投げするといいらしいのでサービスクラスを用意し委譲します。

using System;
using System.Web.Mvc;
using Mvc2App.Models;
using Mvc2App.Services;
using Mvc2App.Services.Abstractions;
using Mvc2App.ViewModels.Peple;

namespace Mvc2App.Controllers
{
    [Authorize]
    public class PepleController : Controller
    {
        IPepleService _service;

        public PepleController() : this(new PepleService())
        { 
        
        }

        public PepleController(IPepleService service)
        {
            _service = service;
        }

        public ActionResult Index()
        {
            var model = _service.Get();
            return View(model);
        }
    }
}
サービスインタフェースとサービスクラスの用意

ビジネスロジック層。
リポジトリよりデータベースへアクセスし、取得した値をビューモデルへ変換するお仕事をします。

using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Mvc2App.Models;
using Mvc2App.ViewModels.Peple;

namespace Mvc2App.Services.Abstractions
{
    public interface IPepleService
    {
        List<PepleViewModel> Get();
    }
}
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Mvc2App.Models;
using Mvc2App.Repositories;
using Mvc2App.Repositories.Abstractions;
using Mvc2App.Services.Abstractions;
using Mvc2App.ViewModels.Peple;

namespace Mvc2App.Services
{  
    public class PepleService : IPepleService
    {
        private IPepleRepository _repository;
        public PepleService():this(new PepleRepository())
        {
 
        }

        public PepleService(IPepleRepository repository)
        {
            _repository = repository;
        }

        public List<PepleViewModel> Get()
        {
            var model = new List<PepleViewModel>();
            var data = _repository.Get();
            foreach (var item in data)
            {
                var person = new PepleViewModel();
                person.ID = item.ID;
                person.Name = item.Name;
                person.Address = item.Address;
                person.PhoneNumber = item.PhoneNumber;
                person.UpdatedBy = item.UpdatedBy;
                person.UpdateDate = item.UpdateDate;
                model.Add(person);
            }
            return model;
        }
    }
}
リポジトリインタフェースとリポジトリクラスの用意

ここがデータ層。Entity Frameworkにてデータベースへアクセスします。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mvc2App.Models;

namespace Mvc2App.Repositories.Abstractions
{
    public interface IPepleRepository
    {
        List<Person> Get();
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Mvc2App.Repositories.Abstractions;
using Mvc2App.Models;

namespace Mvc2App.Repositories
{
    public class PepleRepository : IPepleRepository
    {
        DevEntities dbContext = new DevEntities();

        public List<Person> Get()
        {
            var query = from x in dbContext.Peple
                        orderby x.ID
                        select x;

            return query.ToList();
        }
    }
}
ビューモデルの用意

MVCのM(Model)です。
ASP.NET MVCには3種類のモデルが存在し、入力モデル、ビューモデル、ドメインモデルのうちのビューモデルにあたる部分です。
ビューモデルとはコントローラーからビューに渡される部分になります。

using System;
using System.ComponentModel.DataAnnotations;

namespace Mvc2App.ViewModels.Peple
{
    public class PepleViewModel
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public string PhoneNumber { get; set; }
        public string UpdatedBy { get; set; }
        public DateTime? UpdateDate { get; set; } 
    }
}
ビューの用意

MVCのV(View)です。
厳密に型指定されたビューモデルとして上記で定義したビューモデルを選択します。
ビューデータクラスが表示されない場合は一回ビルドすると出てきます。

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<IEnumerable<Mvc2App.ViewModels.Peple.PepleViewModel>>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	Index
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Index</h2>

    <table>
        <tr>
            <th></th>
            <th>ID</th>
            <th>Name</th>
            <th>Address</th>
            <th>PhoneNumber</th>
            <th>UpdatedBy</th>
            <th>UpdateDate</th>
        </tr>

    <% foreach (var item in Model) { %>
    
        <tr>
            <td>
                <%: Html.ActionLink("Edit", "Edit", new { id=item.ID}) %> |
                <%: Html.ActionLink("Details", "Details", new { id = item.ID })%> |
                <%: Html.ActionLink("Delete", "Delete", new { id = item.ID })%>
            </td>
            <td>
                <%: item.ID %>
            </td>
            <td>
                <%: item.Name %>
            </td>
            <td>
                <%: item.Address %>
            </td>
            <td>
                <%: item.PhoneNumber %>
            </td>
            <td>
                <%: item.UpdatedBy %>
            </td>
            <td>
                <%: item.UpdateDate %>
            </td>
        </tr>    
    <% } %>
    </table>
    <p>
        <%: Html.ActionLink("Create New", "Create") %>
    </p>
</asp:Content>
ソリューションエクスプローラ

フォルダ構成はこんな感じ。
f:id:sh_yoshida:20141104183330p:plain

実行結果

データを登録しhttp://localhost:ポート番号/Pepleへアクセス!


f:id:sh_yoshida:20141104183313p:plain

まとめ

今回の例はチュートリアル程度のアプリだと過剰設計なのでしょうが、実際はより複雑なはずです。経験の浅い私はどんな感じにしたらよいかわかりませんでした。
下記の書籍を読んで、少し複雑な状況に対するアプローチの足がかりが出来た気がします。
アプリケーションアーキテクチャの設計って奥が深いですね。

参考資料

プログラミングMICROSOFT ASP.NET MVC (Microsoft Press)

プログラミングMICROSOFT ASP.NET MVC (Microsoft Press)