ASP.NET core MVC sort機能を作成する

ASP.NET core MVC sort機能を作成する

ASP.NET core MVCで、sort機能を作成する手順を記述してます。.NETのバージョンは6を使用してます。

環境

  • OS windows10 pro
  • IDE Visual Studio 2022
  • .NET 6

プロジェクト作成

「ASP.NET Core Web アプリ(Model-View-Controller)」を選択して「次へ」をクリックします。
※ここでは「aspcoremvc」という名前でプロジェクトを作成してます。

SQLServer

DB「hoge」の「member」テーブルを使用します。

「member」テーブルに、以下のデータを作成してます。

EntityFrameworkCore追加

使用するパッケージを追加しておきます。

「ツール」 > 「NuGet パッケージ マネージャー」 > 「パッケージ マネージャー コンソール」を選択します。

以下の2つを作成したプロジェクトに追加しておきます。

PM> Install-Package -ProjectName プロジェクト名 -Id Microsoft.EntityFrameworkCore.SqlServer
PM> Install-Package -ProjectName プロジェクト名 -Id Microsoft.EntityFrameworkCore.Tools

Model作成

DBに接続して作成します。Scaffold-DbContextを使用して、以下のコマンドを実行してModelを作成します。

DB名 : hoge
ホスト : 192.168.xxx.xxx
ユーザー : sa
パスワード : password
modelを作成するフォルダ : Models
コンテキスト名 : MemberDbContext

PM> Scaffold-DbContext -Provider Microsoft.EntityFrameworkCore.SqlServer -Connection "Data Source=192.168.xxx.xxx;Database=hoge;user id=sa;password=password" -f -OutputDir "Models" -Context "MemberDbContext" -UseDatabaseNames -DataAnnotations

「Models」フォルダ配下に「Model」と「Context」が作成されていることが確認できます。

「member.cs」

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;

namespace aspcoremvc.Models
{
    [Table("member")]
    public partial class member
    {
        [Key]
        public int id { get; set; }
        public int department { get; set; }
        [StringLength(4)]
        [Unicode(false)]
        public string year { get; set; } = null!;
        [StringLength(2)]
        [Unicode(false)]
        public string month { get; set; } = null!;
        public int employee { get; set; }
        [Column(TypeName = "datetime")]
        public DateTime created_data { get; set; }
        [Column(TypeName = "datetime")]
        public DateTime updated_data { get; set; }
    }
}

「MemberDbContext.cs」

using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace aspcoremvc.Models
{
    public partial class MemberDbContext : DbContext
    {
        public MemberDbContext()
        {
        }

        public MemberDbContext(DbContextOptions<MemberDbContext> options)
            : base(options)
        {
        }

        public virtual DbSet<member> members { get; set; } = null!;

//        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
//        {
//            if (!optionsBuilder.IsConfigured)
//            {
//#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
//                optionsBuilder.UseSqlServer("Data Source=192.168.101.187;Database=hoge;user id=sa;password=password");
//            }
//        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<member>(entity =>
            {
                entity.Property(e => e.created_data).HasDefaultValueSql("(getdate())");

                entity.Property(e => e.month).IsFixedLength();

                entity.Property(e => e.updated_data).HasDefaultValueSql("(getdate())");

                entity.Property(e => e.year).IsFixedLength();
            });

            OnModelCreatingPartial(modelBuilder);
        }

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
    }
}

「MemberDbContext.cs」に記述されているDB接続情報は後述の「appsettings.json」で記述するので、コメントアウトしてます。

//        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
//        {
//            if (!optionsBuilder.IsConfigured)
//            {
//#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
//                optionsBuilder.UseSqlServer("Data Source=192.168.xxx.xxx;Database=hoge;user id=sa;password=password");
//            }
//        }

DB接続情報

sqlserverと接続できるように接続情報を追加します。

「appsettings.json」に、以下のコードを追加します。

「ConnectionStrings」を追加します。

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Server=192.168.xxx.xxx;Database=hoge;User ID=sa;Password=password;"
  }
}

サービス登録

サービスに、コンテキストを登録します。「Program.cs」を編集します。

さきほど「appsettings.json」に作成した接続情報「DefaultConnection」を使用して「MemberDbContext」を登録します。

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

// 追加
builder.Services.AddDbContext<MemberDbContext>(
    options => options.UseSqlServer(
        builder.Configuration.GetConnectionString("DefaultConnection")
        )
    );

Controller作成

「Controllers」フォルダ配下に「membersController.cs」を作成します。

#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using aspcoremvc.Models;

namespace aspcoremvc.Controllers
{
    public class membersController : Controller
    {
        private readonly MemberDbContext _context;

        public membersController(MemberDbContext context)
        {
            _context = context;
        }

        
        public ActionResult Index(string memberSort)
        {
           
            ViewBag.MonthSortParm = String.IsNullOrEmpty(memberSort) ? "month_desc" : "";            

            // 全データ取得
            var members = from m in _context.members
                         select m;


            switch (memberSort)
            {
                case "month_desc":
                    members = members.OrderByDescending(s => s.month);
                    break;
                default:                    
                    break;
            }

            return View(members.ToList());
        }

    }
}

View作成

次に「Views」配下に「members」フォルダを作成して配下に「Index.cshtml」を追加しておきます。

@model IEnumerable<aspcoremvc.Models.member>
@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>


<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.department)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.year)
            </th>
            <th>
               @Html.ActionLink("Month", "Index", new { memberSort = ViewBag.MonthSortParm })
            </th>
            <th>
                @Html.DisplayNameFor(model => model.employee)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.created_data)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.updated_data)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>

@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.department)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.year)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.month)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.employee)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.created_data)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.updated_data)
            </td>
        </tr>
}
    </tbody>
</table>

実行

一旦、「F5」キーでデバックを実行して、起動します。

http://localhost:ポート番号/members/ にアクセスするとsort機能が作成されていることが確認できます。