0
0

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#】ASP.NET Coreでテーブル情報を一括更新する方法

Last updated at Posted at 2025-07-28

たとえば、下記の画面で一括処理(POST)をしたいとします。

image.png

画面側でname属性を付与してサーバ側のModelクラスのProperty属性と一致させることで一括データをPOST送信させることができます。

【イメージ】
(フロント側)
@Model[i].employeeId

(サーバ側)
public int employeeId { get; set; }

👆のように全ての input, select, radio, checkboxname="Employees[i].プロパティ名"を付けてます。

フロント側の実装

View/AdminUser/AdminEmployeeMember.cshtml
@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.OptionTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers

@model List<ASPNETSQLServer.Models.AdminEmployeeViewModel>
@{
    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.Count; i++)
                {
                    <tr>
                        <!-- hidden ID -->
                        <td>
                            @Model[i].employeeId
                            <input type="hidden" name="Employees[@i].employeeId" value="@Model[i].employeeId" />
                        </td>

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

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

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

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

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

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

                        <td class="text-center">
                            <input type="checkbox" name="Employees[@i].IpaddressAlocation" value="true" @(Model[i].IpaddressAlocation ? "checked" : "") />
                            <input type="hidden" name="Employees[@i].IpaddressAlocation" value="false" />
                        </td>
                    </tr>
                }
            </tbody>
        </table>
        <button type="submit" class="btn btn-primary">一括送信</button>
    </div>
</form>

バックエンド側の実装

Modelクラスは下記です。

Models/AdminEmployeeViewModel.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; }
}

つづいて、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()
    {
        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}");
                }
            }
        }
        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");
    }
}
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?