今回は、テーブル一覧にページネーションを追加する方法を記載します。
イメージ
バックエンドの新規ファイルと既存ファイルの修正
まずは、ページネーションを作成するためのファイルを作っていきましょう。
Modelクラスの新規作成と修正
こちらは、テーブル一覧に表示するためのEntity
クラスです。
AdminEmployeeViewModel
は1人の従業員情報を表すモデルです。
→ List<AdminEmployeeViewModel>
は一覧。
→ Employees, CurrentPage, TotalPages
などの ページ管理情報はこのモデルに含めるべきではありません。
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
をクラスに保持しています。
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
側に返却します。
// 該当箇所を表示しています。
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);
// 該当箇所を表示
[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>
タグのループ処理も修正を加えていきます。
@*該当箇所のみを表示*@
<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
を活用しています。
@* 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>
全体のコード
▼フロントエンド
@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クラス
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");
}
}