2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C#】テーブル一覧にページネーションを実装する方法

Posted at

今回は、テーブル一覧にページネーションを追加する方法を記載します。

イメージ

1ページ目:
image.png
2ページ目:
image.png

バックエンドの新規ファイルと既存ファイルの修正

まずは、ページネーションを作成するためのファイルを作っていきましょう。

Modelクラスの新規作成と修正

こちらは、テーブル一覧に表示するためのEntityクラスです。
AdminEmployeeViewModel は1人の従業員情報を表すモデルです。
List<AdminEmployeeViewModel> は一覧。
Employees, CurrentPage, TotalPages などの ページ管理情報はこのモデルに含めるべきではありません。

Models/AdminEmployeeViewModels.cs
namespace ASPNETSQLServer.Models;
using System.ComponentModel.DataAnnotations;
using Microsoft.Identity.Client;

public class AdminEmployeeViewModel
{
    [Required]
    public int employeeId { get; set; }
    [Required]
    public string Department { get; set; }
    [Required]
    public string Section { get; set; }
    [Required]
    public string JobClass { get; set; }
    [Required]
    public string EmployeeName { get; set; }
    [Required]
    public string Ipadress { get; set; }
    [Required]
    public string Sex { get; set; }
    public bool IpaddressAlocation { get; set; }
}

ページネーションを実装するために、上記のAdminEmployeeViewModels.csをもとに別のEntityクラスを新規作成します。
このクラスでは、さきほどのテーブル表示するためのAdminEmployeeViewModelsオブジェクトをList化したもののほかに、現在表示されているページ数を表すCurrentPages フィールドと、合計のページ数を表すTotalPages をクラスに保持しています。

Models/PageEmployeeViewModels.cs
namespace ASPNETSQLServer.Models;

public class PagedEmployeeViewModel
{
    public List<AdminEmployeeViewModel> Employees { get; set; }
    public int CurrentPages { get; set; }
    public int TotalPages { get; set; }
}

Controllerクラスの修正

つぎにControllerクラスの修正です。

関数の引数にpageフィールドを用意して画面のページ番号をクリックしたらその番号を受け取るようにします。

つづいて、画面に表示するデータ数(pageSizeフィールドを設定)を設定します。
pageSizeフィールドは、別途設定ファイルに書き出し、Controllerから読み込む方法がスマートです。

さいごに、前述したPageEmployeeViewModels.csにデータを格納してView側に返却します。

Controllers/AdminUsersController.cs
// 該当箇所を表示しています。
int pageSize = 2;
int totalCount = adminEmployeeViewModelsList.Count;
var items = adminEmployeeViewModelsList.Skip((page - 1)*pageSize).Take(pageSize).ToList();
int totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
Controllers/AdminUsersController.cs
// 該当箇所を表示
    [HttpGet]
    public async Task<IActionResult> AdminEmployeeMember(int page)
    {
        string employeeSelectQuery = "SELECT * FROM [test].[dbo].[employee]";
        List<AdminEmployeeViewModel> adminEmployeeViewModelsList = new List<AdminEmployeeViewModel>();
        using (SqlConnection connection = new SqlConnection(_connectString))
        {
            using (SqlCommand command = new SqlCommand(employeeSelectQuery, connection))
            {
                try
                {
                    await connection.OpenAsync();
                    using (SqlDataReader reader = await command.ExecuteReaderAsync())
                    {
                        if (!reader.HasRows)
                        {
                            Object notFoundUser = new { status = 200, message = "ユーザー情報はありませんでした。" };
                            return Json(notFoundUser);
                        }
                        while (await reader.ReadAsync())
                        {
                            AdminEmployeeViewModel adminEmployeeViewModel = new AdminEmployeeViewModel
                            {
                                employeeId = reader["employeeId"] != DBNull.Value ? Convert.ToInt32(reader["employeeId"]) : 0,
                                Department = reader["department"].ToString(),
                                Section = reader["section"].ToString(),
                                JobClass = reader["jobclass"].ToString(),
                                EmployeeName = reader["name"].ToString(),
                                Ipadress = reader["ipaddress"].ToString(),
                                Sex = reader["sex"].ToString(),
                                IpaddressAlocation = reader["ipaddressalocation"] != DBNull.Value ? reader.GetBoolean(reader.GetOrdinal("ipaddressalocation")) : false,
                            };
                            adminEmployeeViewModelsList.Add(adminEmployeeViewModel);
                        }
                    }
                }
                catch (DbException dbException)
                {
                    Console.WriteLine($"データベースエラーが発生しました。。エラーメッセージ:{dbException}");
                }
            }
        }
        // ページネーション追加 2025.7.29
        int pageSize = 2;
        int totalCount = adminEmployeeViewModelsList.Count;
        var items = adminEmployeeViewModelsList.Skip((page - 1)*pageSize).Take(pageSize).ToList();
        int totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
        var viewModel = new PagedEmployeeViewModel
        {
            Employees = items,
            CurrentPages = page,
            TotalPages = totalPages
        };
        return View(viewModel);// return View(adminEmployeeViewModelsList);
    }

フロントエンドの修正

つずいて、cshtml側の修正をしていきます。
@modelは、ASPNETSQLServer.Models.PagedEmployeeViewModelを読み込みます。
これにあわせて、<table>タグのループ処理も修正を加えていきます。

Views/AdminUsers/AdminEmployeeMember.cshtml
@*該当箇所のみを表示*@
            <tbody>
                @for (int i = 0; i < Model.Employees.Count; i++)
                {
                    <tr>
                        <!-- hidden ID -->
                        <td>
                            @Model.Employees[i].employeeId
                            <input type="hidden" name="Employees[@i].employeeId" value="@Model.Employees[i].employeeId" />
                        </td>

                        <td>
                            <select class="form-select" name="Employees[@i].Department">
                                <option value="人事部" selected="@(Model.Employees[i].Department == "人事部")">人事部</option>
                                <option value="経理部" selected="@(Model.Employees[i].Department == "経理部")">経理部</option>
                                <option value="総務部" selected="@(Model.Employees[i].Department == "総務部")">総務部</option>
                                <option value="営業部" selected="@(Model.Employees[i].Department == "営業部")">営業部</option>
                                <option value="技術部" selected="@(Model.Employees[i].Department == "技術部")">技術部</option>
                                <option value="法務部" selected="@(Model.Employees[i].Department == "法務部")">法務部</option>
                                <option value="情報システム部" selected="@(Model.Employees[i].Department == "情報システム部")">情報システム部</option>
                            </select>
                        </td>

                        <td>
                            <select class="form-select" name="Employees[@i].Section">
                                <option value="人事課" selected="@(Model.Employees[i].Section == "人事課")">人事課</option>
                                <option value="経理課" selected="@(Model.Employees[i].Section == "経理課")">経理課</option>
                                <option value="総務課" selected="@(Model.Employees[i].Section == "総務課")">総務課</option>
                                <option value="営業課" selected="@(Model.Employees[i].Section == "営業課")">営業課</option>
                                <option value="技術課" selected="@(Model.Employees[i].Section == "技術課")">技術課</option>
                                <option value="法務課" selected="@(Model.Employees[i].Section == "法務課")">法務課</option>
                                <option value="情報システム課" selected="@(Model.Employees[i].Section == "情報システム課")">情報システム課</option>
                            </select>
                        </td>

                        <td>
                            <select class="form-select" name="Employees[@i].JobClass">
                                <option value="執行役員" selected="@(Model.Employees[i].JobClass == "執行役員")">執行役員</option>
                                <option value="部長" selected="@(Model.Employees[i].JobClass == "部長")">部長</option>
                                <option value="課長" selected="@(Model.Employees[i].JobClass == "課長")">課長</option>
                                <option value="主任" selected="@(Model.Employees[i].JobClass == "主任")">主任</option>
                                <option value="一般社員" selected="@(Model.Employees[i].JobClass == "一般社員")">一般社員</option>
                                <option value="契約社員" selected="@(Model.Employees[i].JobClass == "契約社員")">契約社員</option>
                                <option value="パート・アルバイト" selected="@(Model.Employees[i].JobClass == "パート・アルバイト")">パート・アルバイト</option>
                            </select>
                        </td>

                        <td>
                            <input type="text" class="form-control" name="Employees[@i].EmployeeName" value="@Model.Employees[i].EmployeeName" />
                        </td>

                        <td>
                            <input type="radio" name="Employees[@i].Sex" value="男性" @(Model.Employees[i].Sex == "男性" ? "checked" : "") /> 男
                            <input type="radio" name="Employees[@i].Sex" value="女性" @(Model.Employees[i].Sex == "女性" ? "checked" : "") /> 女
                        </td>

                        <td>
                            <input type="text" class="form-control" name="Employees[@i].Ipadress" value="@Model.Employees[i].Ipadress" />
                        </td>

                        <td class="text-center">
                            <input type="checkbox" name="Employees[@i].IpaddressAlocation" value="true" @(Model.Employees[i].IpaddressAlocation ? "checked" : "") />
                            <input type="hidden" name="Employees[@i].IpaddressAlocation" value="false" />
                        </td>
                    </tr>
                }
            </tbody>

さいごにページネーション処理を追加します。
Razorでページリンクを生成するためasp-route-pageを活用しています。

Views/AdminUsers/AdminEmployeeMember.cshtml
        @* 2025.7.29 追加*@
        <div class="d-flex justify-content-center">  
            <nav aria-label="ページネーション">
                <ul class="pagination">
                    @if (Model.CurrentPages > 1)
                    {
                        <li class="page-item">
                            <a class="page-link" asp-action="AdminEmployeeMember" asp-route-page="@(Model.CurrentPages - 1)">前へ</a>
                        </li>
                    }

                    @for (int i = 1; i <= Model.TotalPages; i++)
                    {
                        <li class="page-item @(i == Model.CurrentPages ? "active" : "")">
                            <a class="page-link" asp-action="AdminEmployeeMember" asp-route-page="@i">@i</a>
                        </li>
                    }

                    @if (Model.CurrentPages < Model.TotalPages)
                    {
                        <li class="page-item">
                            <a class="page-link" asp-action="AdminEmployeeMember" asp-route-page="@(Model.CurrentPages + 1)">次へ</a>
                        </li>
                    }
                </ul>
            </nav>
        </div>

全体のコード

▼フロントエンド

Views/AdminUsers/AdminEmployeeMember.cshtml
@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.OptionTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers

@model ASPNETSQLServer.Models.PagedEmployeeViewModel    
@{
    ViewData["Title"] = "従業員名簿";
}

<form asp-action="SubmitEmployeeList" method="post">
    <div class="text-center">
        <h2>従業員名簿</h2>
        <table class="table table-bordered">
            <thead>
                <tr>
                    <th>従業員ID</th>
                    <th>部署</th>
                    <th>課</th>
                    <th>役職</th>
                    <th>従業員名</th>
                    <th>性別</th>
                    <th>IPアドレス</th>
                    <th>割り当て</th>
                </tr>
            </thead>
            <tbody>
                @for (int i = 0; i < Model.Employees.Count; i++)
                {
                    <tr>
                        <!-- hidden ID -->
                        <td>
                            @Model.Employees[i].employeeId
                            <input type="hidden" name="Employees[@i].employeeId" value="@Model.Employees[i].employeeId" />
                        </td>

                        <td>
                            <select class="form-select" name="Employees[@i].Department">
                                <option value="人事部" selected="@(Model.Employees[i].Department == "人事部")">人事部</option>
                                <option value="経理部" selected="@(Model.Employees[i].Department == "経理部")">経理部</option>
                                <option value="総務部" selected="@(Model.Employees[i].Department == "総務部")">総務部</option>
                                <option value="営業部" selected="@(Model.Employees[i].Department == "営業部")">営業部</option>
                                <option value="技術部" selected="@(Model.Employees[i].Department == "技術部")">技術部</option>
                                <option value="法務部" selected="@(Model.Employees[i].Department == "法務部")">法務部</option>
                                <option value="情報システム部" selected="@(Model.Employees[i].Department == "情報システム部")">情報システム部</option>
                            </select>
                        </td>

                        <td>
                            <select class="form-select" name="Employees[@i].Section">
                                <option value="人事課" selected="@(Model.Employees[i].Section == "人事課")">人事課</option>
                                <option value="経理課" selected="@(Model.Employees[i].Section == "経理課")">経理課</option>
                                <option value="総務課" selected="@(Model.Employees[i].Section == "総務課")">総務課</option>
                                <option value="営業課" selected="@(Model.Employees[i].Section == "営業課")">営業課</option>
                                <option value="技術課" selected="@(Model.Employees[i].Section == "技術課")">技術課</option>
                                <option value="法務課" selected="@(Model.Employees[i].Section == "法務課")">法務課</option>
                                <option value="情報システム課" selected="@(Model.Employees[i].Section == "情報システム課")">情報システム課</option>
                            </select>
                        </td>

                        <td>
                            <select class="form-select" name="Employees[@i].JobClass">
                                <option value="執行役員" selected="@(Model.Employees[i].JobClass == "執行役員")">執行役員</option>
                                <option value="部長" selected="@(Model.Employees[i].JobClass == "部長")">部長</option>
                                <option value="課長" selected="@(Model.Employees[i].JobClass == "課長")">課長</option>
                                <option value="主任" selected="@(Model.Employees[i].JobClass == "主任")">主任</option>
                                <option value="一般社員" selected="@(Model.Employees[i].JobClass == "一般社員")">一般社員</option>
                                <option value="契約社員" selected="@(Model.Employees[i].JobClass == "契約社員")">契約社員</option>
                                <option value="パート・アルバイト" selected="@(Model.Employees[i].JobClass == "パート・アルバイト")">パート・アルバイト</option>
                            </select>
                        </td>

                        <td>
                            <input type="text" class="form-control" name="Employees[@i].EmployeeName" value="@Model.Employees[i].EmployeeName" />
                        </td>

                        <td>
                            <input type="radio" name="Employees[@i].Sex" value="男性" @(Model.Employees[i].Sex == "男性" ? "checked" : "") /> 男
                            <input type="radio" name="Employees[@i].Sex" value="女性" @(Model.Employees[i].Sex == "女性" ? "checked" : "") /> 女
                        </td>

                        <td>
                            <input type="text" class="form-control" name="Employees[@i].Ipadress" value="@Model.Employees[i].Ipadress" />
                        </td>

                        <td class="text-center">
                            <input type="checkbox" name="Employees[@i].IpaddressAlocation" value="true" @(Model.Employees[i].IpaddressAlocation ? "checked" : "") />
                            <input type="hidden" name="Employees[@i].IpaddressAlocation" value="false" />
                        </td>
                    </tr>
                }
            </tbody>
        </table>
        @* 2025.7.29 追加*@
        <div class="d-flex justify-content-center">  
            <nav aria-label="ページネーション">
                <ul class="pagination">
                    @if (Model.CurrentPages > 1)
                    {
                        <li class="page-item">
                            <a class="page-link" asp-action="AdminEmployeeMember" asp-route-page="@(Model.CurrentPages - 1)">前へ</a>
                        </li>
                    }

                    @for (int i = 1; i <= Model.TotalPages; i++)
                    {
                        <li class="page-item @(i == Model.CurrentPages ? "active" : "")">
                            <a class="page-link" asp-action="AdminEmployeeMember" asp-route-page="@i">@i</a>
                        </li>
                    }

                    @if (Model.CurrentPages < Model.TotalPages)
                    {
                        <li class="page-item">
                            <a class="page-link" asp-action="AdminEmployeeMember" asp-route-page="@(Model.CurrentPages + 1)">次へ</a>
                        </li>
                    }
                </ul>
            </nav>
        </div>
        <button type="submit" class="btn btn-primary">一括送信</button>
    </div>
</form>

▼Controllerクラス

Controllers/AdminUserController.cs
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using ASPNETSQLServer.Models;
using Microsoft.Extensions.Configuration;//追加
using Microsoft.Data.SqlClient;
using System.Data.Common;//追加
using ASPNETSQLServer.Models;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Data;
using ASPNETSQLServer.Service;//追加
using Microsoft.AspNetCore.Http;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication; // 追加
using System.Security.Claims; // 追加
using Microsoft.AspNetCore.Authentication; // 追加
using Microsoft.AspNetCore.Authentication.Cookies; // 追加

namespace ASPNETSQLServer.Controllers;

public class AdminUsersController : Controller
{
    private readonly ILogger<AdminUsersController> _logger;
    private readonly string _connectString;
    private readonly PasswordHash passwordHash;
    public AdminUsersController(ILogger<AdminUsersController> logger, IConfiguration configuration, PasswordHash passwordHash)
    {
        _logger = logger;
        _connectString = configuration.GetConnectionString("SqlServerConnection");
        this.passwordHash = passwordHash;
    }
    [HttpGet]
    public IActionResult Index()
    {
        // 既にログインしている場合はDashboardにリダイレクト
        if (User.Identity.IsAuthenticated)
        {
            return RedirectToAction("Dashboard", "AdminUsers");
        }
        return View();
    }

    [HttpPost]
    public async Task<IActionResult> AdminUserLogin(AdminUserViewModel adminUserViewModel)
    {
        string selectQuery = "SELECT name,email,password FROM [test].[dbo].[adminusers] WHERE name = @name AND email = @email";
        string employeeSelectQuery = "SELECT * FROM [test].[dbo].[employee]";
        List<AdminEmployeeViewModel> adminEmployeeViewModelsList = new List<AdminEmployeeViewModel>();
        List<AdminUserViewModel> adminUserViewModelsList = new List<AdminUserViewModel>();
        using (SqlConnection connection = new SqlConnection(_connectString))
        {
            using (SqlCommand command = new SqlCommand(selectQuery, connection))
            {
                command.Parameters.AddWithValue("@name", adminUserViewModel.AdminUserName);
                command.Parameters.AddWithValue("@email", adminUserViewModel.AdminUserEmail);
                try
                {
                    await connection.OpenAsync();
                    using (SqlDataReader reader = await command.ExecuteReaderAsync())
                    {
                        if (!reader.HasRows)
                        {
                            Object notFoundUser = new { status = 200, message = "ユーザー情報はありませんでした。" };
                            return Json(notFoundUser);
                        }
                        while (await reader.ReadAsync())
                        {
                            AdminUserViewModel adminUser = new AdminUserViewModel
                            {
                                AdminUserName = reader["name"].ToString(),
                                AdminUserEmail = reader["email"].ToString(),
                                AdminUserPassword = reader["password"].ToString(),
                            };
                            adminUserViewModelsList.Add(adminUser);
                        }
                    }
                    /*
                    // employeeテーブルから情報を取得 2025.7.28 追加
                    using (SqlDataReader reader = await command.ExecuteReaderAsync())
                    {
                        if (!reader.HasRows)
                        {
                            Object notFoundUser = new { status = 200, message = "ユーザー情報はありませんでした。" };
                            return Json(notFoundUser);
                        }
                        while (await reader.ReadAsync())
                        {
                            AdminEmployeeViewModel adminEmployeeViewModel = new AdminEmployeeViewModel
                            {
                                employeeId = reader["employeeId"] != DBNull.Value ? Convert.ToInt32(reader["employeeId"]) : 0,
                                Department = reader["department"].ToString(),
                                Section = reader["section"].ToString(),
                                JobClass = reader["jobclass"].ToString(),
                                EmployeeName = reader["name"].ToString(),
                                Ipadress = reader["ipaddress"].ToString(),
                                Sex = reader["sex"].ToString(),
                                IpaddressAlocation = reader["ipaddressalocation"] != DBNull.Value ? reader.GetBoolean(reader.GetOrdinal("ipaddressalocation")) : false,
                            };
                            adminEmployeeViewModelsList.Add(adminEmployeeViewModel);
                        }
                    }
                    */
                }
                catch (DbException dbException)
                {
                    Console.WriteLine($"データベースエラーが発生しました。。エラーメッセージ:{dbException}");
                }
                // 取得したデータに基づいて処理を行う
                if (adminUserViewModelsList.Count == 0)
                {
                    return Unauthorized(new { Message = "ユーザー名またはメールアドレスが間違っています。" });
                }
                // パスワードチェック
                string inputHashedPassword = passwordHash.HashPassword(adminUserViewModel.AdminUserPassword);
                if (inputHashedPassword != adminUserViewModelsList[0].AdminUserPassword)
                {
                    return Unauthorized(new { Message = "パスワードが間違っています。" });
                }
                AdminUserViewModel foundUser = adminUserViewModelsList[0];

                // 認証チケットの作成
                var claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name,foundUser.AdminUserName),
                    new Claim(ClaimTypes.Email,foundUser.AdminUserEmail)
                };

                var claimsIdentity = new ClaimsIdentity(
                    claims, CookieAuthenticationDefaults.AuthenticationScheme
                );

                var authProperties = new AuthenticationProperties
                {
                    // AllowRefresh = <bool>,
                    // IsPersistent = true, // 永続的なCookie(ブラウザを閉じても有効)にする場合
                    // ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(30), // 明示的な有効期限を設定
                    RedirectUri = Url.Action("Dashboard", "AdminUsers")// 認証後のリダイレクト先
                };

                // 認証Cookieを発行
                await HttpContext.SignInAsync(
                    CookieAuthenticationDefaults.AuthenticationScheme,
                    new ClaimsPrincipal(claimsIdentity),
                    authProperties
                );
                // セッションにデータを保存(例: ユーザーIDなど)
                // ASP.NET Coreのセッションは、Session Cookieを通じてサーバー側の状態を管理します。
                // 認証に成功したユーザーの識別情報などをセッションに保存することで、
                // 後続のリクエストでそのユーザーの状態を追跡できます。
                HttpContext.Session.SetString("AdminUserName", foundUser.AdminUserName);
                HttpContext.Session.SetString("AdminUserEmail", foundUser.AdminUserEmail);
                _logger.LogInformation($"ユーザー {foundUser.AdminUserName} がログインしました。");
                // ログイン成功後、Dashboardにリダイレクト
                return RedirectToAction("Dashboard", "AdminUsers");
            }
        }

    }

    [HttpGet]
    public IActionResult Dashboard()
    {
        // 認証されているかどうかを確認
        if (!User.Identity.IsAuthenticated)
        {
            // 認証されていない場合はログインページへリダイレクト
            return RedirectToAction("Index", "AdminUsers");
        }
        // セッションからユーザー情報を取得して表示することも可能
        ViewBag.AdminUserName = HttpContext.Session.GetString("AdminUserName");
        ViewBag.AdminUserEmail = HttpContext.Session.GetString("AdminUserEmail");
        return View();
    }

    [HttpGet]
    public async Task<IActionResult> Logout()
    {
        // 認証Cookieを削除し、ログアウト
        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        // セッションをクリア
        HttpContext.Session.Clear();
        _logger.LogInformation("ユーザーがログアウトしました。");
        // ログアウト後、ログインページにリダイレクト
        return RedirectToAction("Index", "AdminUsers");
    }

    [HttpGet]
    public IActionResult AccessDenied()
    {
        return View();
    }

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }

    [HttpGet]
    public IActionResult ArmyMembersRegistration()
    {
        return View();
    }
    [HttpPost]
    public async Task<IActionResult> EmployeeRegister(AdminEmployeeViewModel adminEmployeeViewModel)
    {
        // クエリ文字列
        string insertQuery = @"INSERT INTO 
                                    [test].[dbo].[employee] 
                                    (employeeId,department,section,jobclass,name,ipaddress,sex,ipaddressalocation) 
                                VALUES 
                                    (@employeeId,@department,@section,@jobclass,@name,@ipaddress,@sex,@ipaddressalocation);";
        using (SqlConnection connection = new SqlConnection(_connectString))
        {
            connection.Open();
            SqlTransaction transaction = connection.BeginTransaction();
            SqlCommand command = connection.CreateCommand();
            command.Transaction = transaction;
            try
            {
                command.CommandText = insertQuery;
                command.Parameters.Clear();
                command.Parameters.Add("@employeeId", SqlDbType.Int).Value = adminEmployeeViewModel.employeeId;
                command.Parameters.Add("@department", SqlDbType.NVarChar).Value = adminEmployeeViewModel.Department;
                command.Parameters.Add("@section", SqlDbType.NVarChar).Value = adminEmployeeViewModel.Section;
                command.Parameters.Add("@jobclass", SqlDbType.NVarChar).Value = adminEmployeeViewModel.JobClass;
                command.Parameters.Add("@name", SqlDbType.NVarChar).Value = adminEmployeeViewModel.EmployeeName;
                command.Parameters.Add("@ipaddress", SqlDbType.NVarChar).Value = adminEmployeeViewModel.Ipadress;
                command.Parameters.Add("@sex", SqlDbType.NVarChar).Value = adminEmployeeViewModel.Sex;
                command.Parameters.Add("@ipaddressalocation", SqlDbType.Bit).Value = adminEmployeeViewModel.IpaddressAlocation;
                int executeRow = command.ExecuteNonQuery();
                transaction.Commit();
                Console.WriteLine($"登録完了しました。実行件数:{executeRow}件");
                Object successObj = new { status = 200, message = "登録しました。" };
            }
            catch (DbException dbexception)
            {
                Console.WriteLine($"{dbexception}");
                transaction.Rollback();
            }
            catch (Exception exception)
            {
                Console.WriteLine($"{exception}");
                transaction.Rollback();
            }
        }
        return Redirect("./Index");
    }

    [HttpGet]
    public async Task<IActionResult> AdminEmployeeMember(int page)
    {
        string employeeSelectQuery = "SELECT * FROM [test].[dbo].[employee]";
        List<AdminEmployeeViewModel> adminEmployeeViewModelsList = new List<AdminEmployeeViewModel>();
        using (SqlConnection connection = new SqlConnection(_connectString))
        {
            using (SqlCommand command = new SqlCommand(employeeSelectQuery, connection))
            {
                try
                {
                    await connection.OpenAsync();
                    using (SqlDataReader reader = await command.ExecuteReaderAsync())
                    {
                        if (!reader.HasRows)
                        {
                            Object notFoundUser = new { status = 200, message = "ユーザー情報はありませんでした。" };
                            return Json(notFoundUser);
                        }
                        while (await reader.ReadAsync())
                        {
                            AdminEmployeeViewModel adminEmployeeViewModel = new AdminEmployeeViewModel
                            {
                                employeeId = reader["employeeId"] != DBNull.Value ? Convert.ToInt32(reader["employeeId"]) : 0,
                                Department = reader["department"].ToString(),
                                Section = reader["section"].ToString(),
                                JobClass = reader["jobclass"].ToString(),
                                EmployeeName = reader["name"].ToString(),
                                Ipadress = reader["ipaddress"].ToString(),
                                Sex = reader["sex"].ToString(),
                                IpaddressAlocation = reader["ipaddressalocation"] != DBNull.Value ? reader.GetBoolean(reader.GetOrdinal("ipaddressalocation")) : false,
                            };
                            adminEmployeeViewModelsList.Add(adminEmployeeViewModel);
                        }
                    }
                }
                catch (DbException dbException)
                {
                    Console.WriteLine($"データベースエラーが発生しました。。エラーメッセージ:{dbException}");
                }
            }
        }
        // ページネーション追加 2025.7.29
        //int page = 1;
        int pageSize = 2;
        int totalCount = adminEmployeeViewModelsList.Count;
        var items = adminEmployeeViewModelsList.Skip((page - 1)*pageSize).Take(pageSize).ToList();
        int totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
        var viewModel = new PagedEmployeeViewModel
        {
            Employees = items,
            CurrentPages = page,
            TotalPages = totalPages
        };
        return View(viewModel);// return View(adminEmployeeViewModelsList);
    }

    [HttpPost]
    public IActionResult SubmitEmployeeList(List<AdminEmployeeViewModel> Employees)
    {
        string updateQuery = @"UPDATE [test].[dbo].[employee] WITH (ROWLOCK)
                               SET
                                department = @department,
                                section = @section,
                                jobclass = @jobclass,
                                name = @name,
                                ipaddress = @ipaddress,
                                sex = @sex,
                                ipaddressalocation = @ipaddressalocation
                               WHERE
                                employeeId = @employeeId                               
        ";
        using (SqlConnection connection = new SqlConnection(_connectString))
        {
            connection.Open();
            SqlTransaction transaction = connection.BeginTransaction();
            SqlCommand command = connection.CreateCommand();
            command.Transaction = transaction;
            try
            {
                foreach (var emp in Employees)
                {
                    using (command = new SqlCommand(updateQuery, connection))
                    {
                        command.Parameters.Add("@department", SqlDbType.NVarChar).Value = emp.Department;
                        command.Parameters.Add("@section", SqlDbType.NVarChar).Value = emp.Section;
                        command.Parameters.Add("@jobclass", SqlDbType.NVarChar).Value = emp.JobClass;
                        command.Parameters.Add("@name", SqlDbType.NVarChar).Value = emp.EmployeeName;
                        command.Parameters.Add("@ipaddress", SqlDbType.NVarChar).Value = emp.Ipadress;
                        command.Parameters.Add("@sex", SqlDbType.NVarChar).Value = emp.Sex;
                        command.Parameters.Add("@ipaddressalocation", SqlDbType.Bit).Value = emp.IpaddressAlocation;
                        command.Parameters.Add("@employeeId", SqlDbType.Int).Value = emp.employeeId;

                        // 行ロックを実行
                        int rowsAffected = command.ExecuteNonQuery();
                        Console.WriteLine($"従業員ID: {emp.employeeId} の更新:{rowsAffected}件");
                    }
                }
                // トランザクション実行
                transaction.Commit();
                TempData["Message"] = "一括更新に成功しました。";
            }
            catch (DbException dbexception)
            {
                Console.WriteLine(dbexception);
                _logger.LogError($"データベース接続に失敗しました。エラーメッセージ:{dbexception.Message}");
                transaction.Rollback();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                _logger.LogError($"予期せぬエラーが発生しました。エラーメッセージ:{e.Message}");
                transaction.Rollback();
            }
        }
        // 完了後リダイレクトまたは再表示
        return RedirectToAction("AdminEmployeeMember");
    }
}
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?