窗体应用分页查询 窗体应用WinForm分页查询适用场景WinForm 客户端数据库数据展示、DataGridView 表格分页查询、批量数据加载优化核心目的避免一次性加载海量数据导致窗体卡顿、内存溢出实现按需分页加载数据提升客户端流畅度**一、分页核心原理**窗体分页查询本质是 数据库端分页核心。客户端传递分页参数给数据库数据库只返回当前页数据最大限度减少数据传输和内存占用。必备分页参数页码PageIndex当前展示的页数默认从 1 开始页容量PageSize每页展示的数据条数常用 10、20、50总条数TotalCount符合查询条件的所有数据总数用于计算总页数总页数TotalPage根据总条数和页容量计算得出核心计算公式总页数 总条数 % 页容量 0 ? 总条数 / 页容量 : 总条数 / 页容量 1数据偏移量SQL 跳过条数 (页码 - 1) * 页容量**二、SQL 分页查询语句SQL Server**1. 基础分页语句– 分页查询数据SELECT * FROM 数据表名WHERE 筛选条件ORDER BY 主键/排序字段 – 分页必须排序否则数据会错乱OFFSET (PageIndex-1)PageSize ROWSFETCH NEXT PageSize ROWS ONLY;– 查询符合条件的总数据条数用于计算分页SELECT COUNT() FROM 数据表名 WHERE 筛选条件;语句说明OFFSET跳过指定条数的数据FETCH NEXT … ROWS ONLY读取指定条数的数据必须加 ORDER BY数据库默认无序不加排序会导致每页数据重复、错乱三、通用分页实体类// 当前页数据集合public List DataList { get; set; } new List();// 符合条件的数据总条数public int TotalCount { get; set; }// 计算后的总页数public int TotalPage { get; set; }////// 当前页码///public int PageIndex { get; set; }// 每页展示条数public int PageSize { get; set; }// 统一计算总页数public void ComputeTotalPage(){if (PageSize 0){TotalPage 0;return;}TotalPage (int)Math.Ceiling(TotalCount / (double)PageSize);}public class PageQueryParam{// 默认第一页public int PageIndex { get; set; } 1;// 项目统一默认每页10条public int PageSize { get; set; } 10;// 计算跳过数据数public int GetSkip(){return (PageIndex - 1) * PageSize;}}四、核心分页查询业务封装通用分页查询方法传入 SQL、分页参数直接返回分页结果适配所有数据表。/// 对应数据库实体/// 条件语句不带ORDER BY、不带分页/// 排序语句必填例如ORDER BY Id DESC/// 分页参数/// SQL防注入参数/// 分页结果实体public PageResult GetPageList(string whereSql, string orderBySql, PageQueryParam pageParam, params SqlParameter[] sqlParams) where T : new(){PageResult pageResult new PageResult();pageResult.PageIndex pageParam.PageIndex;pageResult.PageSize pageParam.PageSize;// 1. 拼接统计总条数SQLstring countSql $“SELECT COUNT(*) FROM 表名 WHERE 11 {whereSql}”;int totalCount Convert.ToInt32(SqlHelper.ExecuteScalar(countSql, sqlParams));pageResult.TotalCount totalCount;pageResult.ComputeTotalPage();// 无数据直接返回空if (totalCount 0)return pageResult;// 2. 拼接分页查询SQL项目固定OFFSET FETCH写法string dataSql $“SELECT * FROM T_UserInfoWHERE 11 {whereSql}{orderBySql}OFFSET Skip ROWSFETCH NEXT PageSize ROWS ONLY”;// 3. 新增分页参数var paramList sqlParams.ToList();paramList.Add(new SqlParameter(“Skip”, pageParam.GetSkip()));paramList.Add(new SqlParameter(“PageSize”, pageParam.PageSize));// 4. 查询并绑定数据pageResult.DataList SqlHelper.QueryBySql(dataSql, paramList.ToArray());return pageResult;五、窗体前端分页控件交互逻辑窗体界面常用上一页、下一页、首页、末页、页码输入、每页条数选择 功能1. 窗体全局分页变量// 分页入参实例private PageQueryParam _pageParam new PageQueryParam();// 分页结果实例private PageResult _pageResult new PageResult();// 页面搜索条件private string _searchKey string.Empty;2. 核心加载数据方法////// 本周项目通用加载分页数据方法/// 包含模糊查询、条件筛选、分页绑定、界面刷新全套逻辑/// 所有分页页面直接调用该方法即可///private void LoadDataByPage(){try{// 1. 初始化条件拼接string where string.Empty;List paramList new List();// 模糊查询条件if (!string.IsNullOrEmpty(_searchKey)){where AND UserName LIKE SearchKey OR Phone LIKE SearchKey;paramList.Add(new SqlParameter(“SearchKey”, $“%{_searchKey}%”));}// 固定筛选只查询未删除数据where AND IsDelete 0;// 2. 调用通用分页方法_pageResult GetPageList(where, “ORDER BY CreateTime DESC, Id DESC”, _pageParam, paramList.ToArray());// 3. 绑定DataGridViewdgv_Data.AutoGenerateColumns false;dgv_Data.DataSource null;dgv_Data.DataSource _pageResult.DataList;// 4. 刷新分页状态栏文本lblPageTip.Text KaTeX parse error: Expected EOF, got } at position 91: …TotalPage} 页; }̲ } catch (Excep…“数据加载失败{ex.Message}”, “系统提示”, MessageBoxButtons.OK, MessageBoxIcon.Error);}3. 分页按钮点击事件// 首页private void btnFirst_Click(object sender, EventArgs e){_pageParam.PageIndex 1;LoadDataByPage();}// 上一页private void btnPrev_Click(object sender, EventArgs e){if (_pageParam.PageIndex 1){_pageParam.PageIndex–;LoadDataByPage();}}// 下一页private void btnNext_Click(object sender, EventArgs e){if (_pageParam.PageIndex _pageResult.TotalPage){_pageParam.PageIndex;LoadDataByPage();}}// 末页private void btnLast_Click(object sender, EventArgs e){_pageParam.PageIndex _pageResult.TotalPage;LoadDataByPage();}// 搜索按钮点击事件private void btnSearch_Click(object sender, EventArgs e){// 搜索重置为第一页_pageParam.PageIndex 1;_searchKey txtSearch.Text.Trim();LoadDataByPage();}// 重置按钮private void btnReset_Click(object sender, EventArgs e){txtSearch.Clear();_searchKey string.Empty;_pageParam.PageIndex 1;LoadDataByPage();}六、常见问题与踩坑记录分页数据重复/错乱原因未添加 ORDER BY 排序数据库分页依赖有序数据集。解决分页 SQL 必须添加稳定排序主键、时间戳。切换页码数据不刷新原因DataGridView 数据源未清空缓存残留旧数据。解决绑定新数据前先设置DataSource null。总页数计算错误原因未对取余结果判断直接整除。解决使用笔记中封装的CalcTotalPage 方法自动计算。页码越界报错解决切换页码前判断当前页码不能小于1、不能大于总页数。