1
2

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#】Web FormのLIstViewを使った高速化

1
Posted at

ASP.NET Web FormによるListViewの表示処理の高速化についてです。

10万件のデータを「0.0005秒程度」で表示するのは物理的に厳しいですが(ページ読み込み+DBアクセス+ASP.NET処理時間を含めての意味なら現実的には 数十ms〜数百ms台が限界)、極限まで高速にページネーション表示する方法は以下の通りです。

完成イメージ

image.png

✅ パフォーマンス高速化のアプローチ(概要)

1.SQL側でページング(OFFSET FETCH)を使って最小限のデータを取得

2.SQLにインデックスを正しく設定(ORDER BY列に)

3.ListViewの仮想ページングではなく、自前でデータを制御

4.無駄な全件取得(今のような全読み込み)をしない

5.クライアント側キャッシュ(オプション)

テーブルにインデックスを設定(SQL Server)

CreateIndex.sql
CREATE NONCLUSTERED INDEX IX_employee_employeeId
ON [test].[dbo].[employee](employeeId);

image.png

修正したコード

sample4.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="sample4.aspx.cs" Inherits="WebApplicationWebForm.sample4" %>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta charset="utf-8" />
    <title>ListViewページング</title>
</head>
<body>
    <form id="form2" runat="server">
        <asp:ListView ID="ListViewClass" runat="server"
            AllowPaging="false" AllowSorting="true"
            OnItemDataBound="ListViewClass_ItemDataBound"
            OnSorting="ListViewClass_Sorting">
            <LayoutTemplate>
                <table border="1" style="width:100%">
                    <thead>
                        <tr>
                            <th><asp:LinkButton ID="SortEmployeeId" runat="server" CommandName="Sort" CommandArgument="employeeId">従業員ID</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortDepartment" runat="server" CommandName="Sort" CommandArgument="department">所属部署</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortSection" runat="server" CommandName="Sort" CommandArgument="section">所属課</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortJobClass" runat="server" CommandName="Sort" CommandArgument="jobclass">役職</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortName" runat="server" CommandName="Sort" CommandArgument="name">従業員名</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortSex" runat="server" CommandName="Sort" CommandArgument="sex">性別</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortIP" runat="server" CommandName="Sort" CommandArgument="ipaddress">IP</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortIPAlloc" runat="server" CommandName="Sort" CommandArgument="ipaddressalocation">割り振り</asp:LinkButton></th>
                        </tr>
                    </thead>
                    <tbody>
                        <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
                    </tbody>
                </table>
            </LayoutTemplate>
            <ItemTemplate>
                <tr>
                    <td><%# Eval("EmployeeId") %></td>
                    <td><%# Eval("Department") %></td>
                    <td><%# Eval("Section") %></td>
                    <td><%# Eval("JobClass") %></td>
                    <td><%# Eval("Name") %></td>
                    <td><%# Eval("Sex") %></td>
                    <td><%# Eval("Ipaddress") %></td>
                    <td><%# Convert.ToBoolean(Eval("IpaddressAlocation")) ? "○" : "×" %></td>
                </tr>
            </ItemTemplate>
        </asp:ListView>

        <!-- ✅ ページングリンクをRepeaterで作成 -->
        <div style="text-align:center; margin-top:10px;">
            <asp:Repeater ID="PagerRepeater" runat="server" OnItemCommand="PagerRepeater_ItemCommand">
                <ItemTemplate>
                    <asp:LinkButton runat="server" CommandName="Page" CommandArgument='<%# Eval("PageIndex") %>'>
                        <%# Eval("DisplayText") %>
                    </asp:LinkButton>
                    &nbsp;
                </ItemTemplate>
            </asp:Repeater>
        </div>

    </form>
</body>
</html>

sample4.aspx.cs
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Configuration;
using System.Web.UI.WebControls;

namespace WebApplicationWebForm
{
    public partial class sample4 : System.Web.UI.Page
    {
        private int PageSize => 2;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ViewState["PageIndex"] = 0;
                LoadListView();
                LoadPager();
            }
        }

        private void LoadListView()
        {
            int pageIndex = (int)ViewState["PageIndex"];
            int offset = pageIndex * PageSize;

            string connStr = ConfigurationManager.ConnectionStrings["sqlserver"].ConnectionString;
            List<Sample4Employee> employees = new List<Sample4Employee>();

            using (SqlConnection conn = new SqlConnection(connStr))
            {
                string sql = $@"
                    SELECT employeeId, department, section, jobclass, name, sex, ipaddress, ipaddressalocation
                    FROM [test].[dbo].[employee]
                    ORDER BY {SortExpression} {SortDirection}
                    OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY";

                using (SqlCommand cmd = new SqlCommand(sql, conn))
                {
                    cmd.Parameters.AddWithValue("@Offset", offset);
                    cmd.Parameters.AddWithValue("@PageSize", PageSize);

                    conn.Open();
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            employees.Add(new Sample4Employee
                            {
                                EmployeeId = Convert.ToInt32(reader["employeeId"]),
                                Department = reader["department"].ToString(),
                                Section = reader["section"].ToString(),
                                JobClass = reader["jobclass"].ToString(),
                                Name = reader["name"].ToString(),
                                Sex = reader["sex"].ToString(),
                                Ipaddress = reader["ipaddress"].ToString(),
                                IpaddressAlocation = reader["ipaddressalocation"] != DBNull.Value &&
                                                     Convert.ToBoolean(reader["ipaddressalocation"])
                            });
                        }
                    }
                }
            }

            ListViewClass.DataSource = employees;
            ListViewClass.DataBind();
        }

        private void LoadPager()
        {
            int total = GetTotalRowCount();
            int totalPages = (int)Math.Ceiling(total / (double)PageSize);

            var pagerItems = new List<dynamic>();

            // 先頭
            pagerItems.Add(new { PageIndex = 0, DisplayText = "先頭" });

            // 番号
            for (int i = 0; i < totalPages; i++)
            {
                pagerItems.Add(new { PageIndex = i, DisplayText = (i + 1).ToString() });
            }

            // 最後尾
            pagerItems.Add(new { PageIndex = totalPages - 1, DisplayText = "最後尾" });

            PagerRepeater.DataSource = pagerItems;
            PagerRepeater.DataBind();
        }

        private int GetTotalRowCount()
        {
            string connStr = ConfigurationManager.ConnectionStrings["sqlserver"].ConnectionString;
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                string sql = "SELECT COUNT(*) FROM [test].[dbo].[employee]";
                using (SqlCommand cmd = new SqlCommand(sql, conn))
                {
                    conn.Open();
                    return (int)cmd.ExecuteScalar();
                }
            }
        }

        protected void PagerRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            if (e.CommandName == "Page")
            {
                ViewState["PageIndex"] = Convert.ToInt32(e.CommandArgument);
                LoadListView();
                LoadPager();
            }
        }

        protected void ListViewClass_Sorting(object sender, ListViewSortEventArgs e)
        {
            if (SortExpression == e.SortExpression)
            {
                SortDirection = (SortDirection == "ASC") ? "DESC" : "ASC";
            }
            else
            {
                SortExpression = e.SortExpression;
                SortDirection = "ASC";
            }

            ViewState["PageIndex"] = 0;
            LoadListView();
            LoadPager();
        }

        protected void ListViewClass_ItemDataBound(object sender, ListViewItemEventArgs e)
        {
            // 任意: 装飾やロジック
        }

        private string SortExpression
        {
            get => ViewState["SortExpression"] as string ?? "employeeId";
            set => ViewState["SortExpression"] = value;
        }

        private string SortDirection
        {
            get => ViewState["SortDirection"] as string ?? "ASC";
            set => ViewState["SortDirection"] = value;
        }
    }

    public class Sample4Employee
    {
        public int EmployeeId { get; set; }
        public string Department { get; set; }
        public string Section { get; set; }
        public string JobClass { get; set; }
        public string Name { get; set; }
        public string Sex { get; set; }
        public string Ipaddress { get; set; }
        public bool IpaddressAlocation { get; set; }
    }
}

トラブルシューティング

番号リンクがリンクになっていないので、画面の切り替えができない

(修正前のコード)

sample4.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="sample4.aspx.cs" Inherits="WebApplicationWebForm.sample4" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>ListView表示</title>
</head>
<body>
    <form id="form2" runat="server">
        <asp:ListView ID="ListViewClass" runat="server" 
            AllowPaging="false" AllowSorting="true"
            OnItemDataBound="ListViewClass_ItemDataBound"
            OnSorting="ListViewClass_Sorting"
            OnPagePropertiesChanging="ListViewClass_PagePropertiesChanging">
            <LayoutTemplate>
                <table border="1">
                    <thead>
                        <tr>
                            <th><asp:LinkButton ID="SortEmployeeId" runat="server" CommandName="Sort" CommandArgument="employeeId">従業員ID</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortDepartment" runat="server" CommandName="Sort" CommandArgument="department">所属部署</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortSection" runat="server" CommandName="Sort" CommandArgument="section">所属課</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortJobClass" runat="server" CommandName="Sort" CommandArgument="jobclass">役職</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortName" runat="server" CommandName="Sort" CommandArgument="name">従業員名</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortSex" runat="server" CommandName="Sort" CommandArgument="sex">性別</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortIP" runat="server" CommandName="Sort" CommandArgument="ipaddress">IPアドレス</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortIPAlloc" runat="server" CommandName="Sort" CommandArgument="ipaddressalocation">割り振り</asp:LinkButton></th>
                        </tr>
                    </thead>
                    <tbody>
                        <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
                    </tbody>
                </table>
            </LayoutTemplate>
            <ItemTemplate>
                <tr>
                    <td><%# Eval("EmployeeId") %></td>
                    <td><%# Eval("Department") %></td>
                    <td><%# Eval("Section") %></td>
                    <td><%# Eval("JobClass") %></td>
                    <td><%# Eval("Name") %></td>
                    <td><%# Eval("Sex") %></td>
                    <td><%# Eval("Ipaddress") %></td>
                    <td><%# Convert.ToBoolean(Eval("IpaddressAlocation")) ? "○" : "×" %></td>
                </tr>
            </ItemTemplate>
        </asp:ListView>

        <div style="margin-top:10px; text-align:center;">
            <asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListViewClass" PageSize="2">
                  <Fields>
                    <asp:NextPreviousPagerField 
                        ShowFirstPageButton="true" 
                        ShowPreviousPageButton="false"
                        FirstPageText="先頭"
                        ButtonType="Link" />

                    <asp:NumericPagerField 
                        ButtonCount="10"
                        ButtonType="Link" />

                    <asp:NextPreviousPagerField 
                        ShowNextPageButton="false" 
                        ShowLastPageButton="true"
                        LastPageText="最後尾"
                        ButtonType="Link" />
                </Fields>
            </asp:DataPager>
        </div>
    </form>
</body>
</html>
sample4.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;
using WebApplicationWebForm.Models;

namespace WebApplicationWebForm
{
    public partial class sample4 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                // 最初のページ(先頭)からデータ読み込み
                DataPager1.SetPageProperties(0, DataPager1.PageSize, true);
                //DataPager1.TotalRowCount = GetTotalRowCount();
                LoadListView();
            }
        }

        private void LoadListView()
        {
            int pageSize = DataPager1.PageSize;
            int pageIndex = GetPageIndex();
            int offset = pageIndex * pageSize;

            string connStr = ConfigurationManager.ConnectionStrings["sqlserver"].ConnectionString;
            List<Sample4Employee> employeeList = new List<Sample4Employee>();

            using (SqlConnection conn = new SqlConnection(connStr))
            {
                string sql = $@"
                    SELECT employeeId, department, section, jobclass, name, sex, ipaddress, ipaddressalocation
                    FROM [test].[dbo].[employee]
                    ORDER BY {SortExpression} {SortDirection}
                    OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY";

                using (SqlCommand cmd = new SqlCommand(sql, conn))
                {
                    cmd.Parameters.AddWithValue("@Offset", offset);
                    cmd.Parameters.AddWithValue("@PageSize", pageSize);

                    conn.Open();
                    SqlDataReader reader = cmd.ExecuteReader();

                    while (reader.Read())
                    {
                        employeeList.Add(new Sample4Employee
                        {
                            EmployeeId = Convert.ToInt32(reader["employeeId"]),
                            Department = reader["department"].ToString(),
                            Section = reader["section"].ToString(),
                            JobClass = reader["jobclass"].ToString(),
                            Name = reader["name"].ToString(),
                            Sex = reader["sex"].ToString(),
                            Ipaddress = reader["ipaddress"].ToString(),
                            IpaddressAlocation = reader["ipaddressalocation"] != DBNull.Value ? Convert.ToBoolean(reader["ipaddressalocation"]) : false
                        });
                    }
                }
            }

            ListViewClass.DataSource = employeeList;
            ListViewClass.DataBind();
        }

        private int GetPageIndex()
        {
            return (DataPager1.StartRowIndex / DataPager1.PageSize);
        }

        private int GetTotalRowCount()
        {
            string connStr = ConfigurationManager.ConnectionStrings["sqlserver"].ConnectionString;
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                string sql = "SELECT COUNT(*) FROM [test].[dbo].[employee]";
                using (SqlCommand cmd = new SqlCommand(sql, conn))
                {
                    conn.Open();
                    return (int)cmd.ExecuteScalar();
                }
            }
        }

        protected void ListViewClass_PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
        {
            DataPager1.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
            LoadListView();
        }

        protected void ListViewClass_Sorting(object sender, ListViewSortEventArgs e)
        {
            if (SortExpression == e.SortExpression)
            {
                SortDirection = (SortDirection == "ASC") ? "DESC" : "ASC";
            }
            else
            {
                SortExpression = e.SortExpression;
                SortDirection = "ASC";
            }

            DataPager1.SetPageProperties(0, DataPager1.PageSize, true);
            LoadListView();
        }

        protected void ListViewClass_ItemDataBound(object sender, ListViewItemEventArgs e)
        {
            if (e.Item.ItemType == ListViewItemType.DataItem)
            {
                var employee = (Sample4Employee)((ListViewDataItem)e.Item).DataItem;
                //var employee = (Employee)((ListViewDataItem)e.Item).DataItem;
                // 色分けロジック(必要に応じて)
                // if (employee.Sex == "男") e.Item.BackColor = System.Drawing.Color.LightBlue;
                // else if (employee.Sex == "女") e.Item.BackColor = System.Drawing.Color.MistyRose;
            }
        }

        // ソート状態保持
        private string SortExpression
        {
            get => ViewState["SortExpression"] as string ?? "employeeId";
            set => ViewState["SortExpression"] = value;
        }

        private string SortDirection
        {
            get => ViewState["SortDirection"] as string ?? "ASC";
            set => ViewState["SortDirection"] = value;
        }
    }

    // モデルクラス
    public class Sample4Employee
    {
        public int EmployeeId { get; set; }
        public string Department { get; set; }
        public string Section { get; set; }
        public string JobClass { get; set; }
        public string Name { get; set; }
        public string Sex { get; set; }
        public string Ipaddress { get; set; }
        public bool IpaddressAlocation { get; set; }
    }

}

(原因)

「番号リンクが表示されるが押せない(動かない)」という原因は、AllowPaging="false" の設定と DataPager の仕様のミスマッチによるものです。

❌ 今の問題点

AllowPaging="false"ListView 側でのページングはオフ → これは SQL側でOFFSET/FETCHを使うために必要

しかし、DataPager AllowPaging="true" の前提で動作する部分がある(内部で ListView をトリガーにするため)

結果、ページ番号は出るがリンクとして動作しない状態になります。

✅ 解決策

👉 解決には以下のように ページングのロジックを完全にカスタムで制御する必要があります:

DataPager の代わりに 独自でページ番号リンクを出力(例:リピーターなど)

または AllowPaging="true" にしてListViewの自動ページングに任せる(ただし SQLページングでなくなり非推奨)

✅ 今回の要件(SQL OFFSET/FETCH + 高速)に合わせた対応

✅ 解決方法(推奨)

DataPager を使わず、自作のページ番号リンクを作り、ボタンクリックでページ切替する方法。

✅ 最終形コード(修正版)

sample4.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="sample4.aspx.cs" Inherits="WebApplicationWebForm.sample4" %>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta charset="utf-8" />
    <title>ListViewページング</title>
</head>
<body>
    <form id="form2" runat="server">
        <asp:ListView ID="ListViewClass" runat="server"
            AllowPaging="false" AllowSorting="true"
            OnItemDataBound="ListViewClass_ItemDataBound"
            OnSorting="ListViewClass_Sorting">
            <LayoutTemplate>
                <table border="1" style="width:100%">
                    <thead>
                        <tr>
                            <th><asp:LinkButton ID="SortEmployeeId" runat="server" CommandName="Sort" CommandArgument="employeeId">従業員ID</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortDepartment" runat="server" CommandName="Sort" CommandArgument="department">所属部署</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortSection" runat="server" CommandName="Sort" CommandArgument="section">所属課</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortJobClass" runat="server" CommandName="Sort" CommandArgument="jobclass">役職</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortName" runat="server" CommandName="Sort" CommandArgument="name">従業員名</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortSex" runat="server" CommandName="Sort" CommandArgument="sex">性別</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortIP" runat="server" CommandName="Sort" CommandArgument="ipaddress">IP</asp:LinkButton></th>
                            <th><asp:LinkButton ID="SortIPAlloc" runat="server" CommandName="Sort" CommandArgument="ipaddressalocation">割り振り</asp:LinkButton></th>
                        </tr>
                    </thead>
                    <tbody>
                        <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
                    </tbody>
                </table>
            </LayoutTemplate>
            <ItemTemplate>
                <tr>
                    <td><%# Eval("EmployeeId") %></td>
                    <td><%# Eval("Department") %></td>
                    <td><%# Eval("Section") %></td>
                    <td><%# Eval("JobClass") %></td>
                    <td><%# Eval("Name") %></td>
                    <td><%# Eval("Sex") %></td>
                    <td><%# Eval("Ipaddress") %></td>
                    <td><%# Convert.ToBoolean(Eval("IpaddressAlocation")) ? "○" : "×" %></td>
                </tr>
            </ItemTemplate>
        </asp:ListView>

        <!-- ✅ ページングリンクをRepeaterで作成 -->
        <div style="text-align:center; margin-top:10px;">
            <asp:Repeater ID="PagerRepeater" runat="server" OnItemCommand="PagerRepeater_ItemCommand">
                <ItemTemplate>
                    <asp:LinkButton runat="server" CommandName="Page" CommandArgument='<%# Eval("PageIndex") %>'>
                        <%# Eval("DisplayText") %>
                    </asp:LinkButton>
                    &nbsp;
                </ItemTemplate>
            </asp:Repeater>
        </div>

    </form>
</body>
</html>

sample4.aspx.cs
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Configuration;
using System.Web.UI.WebControls;

namespace WebApplicationWebForm
{
    public partial class sample4 : System.Web.UI.Page
    {
        private int PageSize => 2;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ViewState["PageIndex"] = 0;
                LoadListView();
                LoadPager();
            }
        }

        private void LoadListView()
        {
            int pageIndex = (int)ViewState["PageIndex"];
            int offset = pageIndex * PageSize;

            string connStr = ConfigurationManager.ConnectionStrings["sqlserver"].ConnectionString;
            List<Sample4Employee> employees = new List<Sample4Employee>();

            using (SqlConnection conn = new SqlConnection(connStr))
            {
                string sql = $@"
                    SELECT employeeId, department, section, jobclass, name, sex, ipaddress, ipaddressalocation
                    FROM [test].[dbo].[employee]
                    ORDER BY {SortExpression} {SortDirection}
                    OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY";

                using (SqlCommand cmd = new SqlCommand(sql, conn))
                {
                    cmd.Parameters.AddWithValue("@Offset", offset);
                    cmd.Parameters.AddWithValue("@PageSize", PageSize);

                    conn.Open();
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            employees.Add(new Sample4Employee
                            {
                                EmployeeId = Convert.ToInt32(reader["employeeId"]),
                                Department = reader["department"].ToString(),
                                Section = reader["section"].ToString(),
                                JobClass = reader["jobclass"].ToString(),
                                Name = reader["name"].ToString(),
                                Sex = reader["sex"].ToString(),
                                Ipaddress = reader["ipaddress"].ToString(),
                                IpaddressAlocation = reader["ipaddressalocation"] != DBNull.Value &&
                                                     Convert.ToBoolean(reader["ipaddressalocation"])
                            });
                        }
                    }
                }
            }

            ListViewClass.DataSource = employees;
            ListViewClass.DataBind();
        }

        private void LoadPager()
        {
            int total = GetTotalRowCount();
            int totalPages = (int)Math.Ceiling(total / (double)PageSize);

            var pagerItems = new List<dynamic>();

            // 先頭
            pagerItems.Add(new { PageIndex = 0, DisplayText = "先頭" });

            // 番号
            for (int i = 0; i < totalPages; i++)
            {
                pagerItems.Add(new { PageIndex = i, DisplayText = (i + 1).ToString() });
            }

            // 最後尾
            pagerItems.Add(new { PageIndex = totalPages - 1, DisplayText = "最後尾" });

            PagerRepeater.DataSource = pagerItems;
            PagerRepeater.DataBind();
        }

        private int GetTotalRowCount()
        {
            string connStr = ConfigurationManager.ConnectionStrings["sqlserver"].ConnectionString;
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                string sql = "SELECT COUNT(*) FROM [test].[dbo].[employee]";
                using (SqlCommand cmd = new SqlCommand(sql, conn))
                {
                    conn.Open();
                    return (int)cmd.ExecuteScalar();
                }
            }
        }

        protected void PagerRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            if (e.CommandName == "Page")
            {
                ViewState["PageIndex"] = Convert.ToInt32(e.CommandArgument);
                LoadListView();
                LoadPager();
            }
        }

        protected void ListViewClass_Sorting(object sender, ListViewSortEventArgs e)
        {
            if (SortExpression == e.SortExpression)
            {
                SortDirection = (SortDirection == "ASC") ? "DESC" : "ASC";
            }
            else
            {
                SortExpression = e.SortExpression;
                SortDirection = "ASC";
            }

            ViewState["PageIndex"] = 0;
            LoadListView();
            LoadPager();
        }

        protected void ListViewClass_ItemDataBound(object sender, ListViewItemEventArgs e)
        {
            // 任意: 装飾やロジック
        }

        private string SortExpression
        {
            get => ViewState["SortExpression"] as string ?? "employeeId";
            set => ViewState["SortExpression"] = value;
        }

        private string SortDirection
        {
            get => ViewState["SortDirection"] as string ?? "ASC";
            set => ViewState["SortDirection"] = value;
        }
    }

    public class Sample4Employee
    {
        public int EmployeeId { get; set; }
        public string Department { get; set; }
        public string Section { get; set; }
        public string JobClass { get; set; }
        public string Name { get; set; }
        public string Sex { get; set; }
        public string Ipaddress { get; set; }
        public bool IpaddressAlocation { get; set; }
    }
}

1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?