You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#循环/列表中处理SQL Server分页查询结果

问题分析与解决方案

当前做法的问题

你的T-SQL脚本通过循环返回多个独立的结果集(每页一个结果集),但默认的.NET数据访问逻辑只会读取第一个结果集,导致currentItemVersion和itemVersionHistory只拿到第一页数据。同时,数据库端循环分页的方式会增加数据库与应用端的交互次数,效率较低,不是最优方案。


解决方案

根据数据量大小,提供两种可行方案:

方案一:一次性获取所有数据(小数据量场景)

如果数据总量不大,直接取消分页逻辑,一次性查询所有数据:

SELECT FruitName, Price 
FROM SampleFruits
ORDER BY Price

.NET端直接读取全量数据到列表,后续处理逻辑保持不变即可。

方案二:.NET端控制分页加载(大数据量场景)

将分页逻辑移到应用端,循环调用单页查询接口,合并所有页数据:

1. 修改T-SQL为参数化单页查询

-- 接收.NET传入的分页参数
DECLARE @PageNumber INT = @InputPageNumber
DECLARE @RowsOfPage INT = @InputRowsPerPage

-- 返回当前页数据
SELECT FruitName, Price 
FROM SampleFruits
ORDER BY Price 
    OFFSET (@PageNumber-1) * @RowsOfPage ROWS
    FETCH NEXT @RowsOfPage ROWS ONLY

-- 返回总页数,用于应用端判断循环次数
SELECT CEILING(COUNT(*) / CAST(@RowsOfPage AS FLOAT)) AS TotalPages
FROM SampleFruits

2. .NET端实现分页循环加载

int rowsPerPage = 4;
int currentPage = 1;
int totalPages = 0;

List<Item> currentItemVersion = new List<Item>();
List<Item> itemVersionHistory = new List<Item>();

// 工具方法:封装分页查询逻辑
List<Item> GetPageData(int pageNum, int pageSize)
{
    var pageItems = new List<Item>();
    using (var conn = new SqlConnection("你的数据库连接字符串"))
    {
        conn.Open();
        var cmd = new SqlCommand("你的分页SQL语句", conn);
        cmd.Parameters.AddWithValue("@InputPageNumber", pageNum);
        cmd.Parameters.AddWithValue("@InputRowsPerPage", pageSize);
        
        using (var reader = cmd.ExecuteReader())
        {
            // 读取当前页数据
            while (reader.Read())
            {
                pageItems.Add(new Item
                {
                    FruitName = reader["FruitName"].ToString(),
                    Price = (decimal)reader["Price"],
                    // 映射其他字段
                });
            }
            // 读取总页数(仅第一页需要)
            if (pageNum == 1 && reader.NextResult() && reader.Read())
            {
                totalPages = (int)reader["TotalPages"];
            }
        }
    }
    return pageItems;
}

// 加载第一页并获取总页数
currentItemVersion.AddRange(GetPageData(1, rowsPerPage));

// 循环加载剩余页数
for (int page = 2; page <= totalPages; page++)
{
    currentItemVersion.AddRange(GetPageData(page, rowsPerPage));
}

// 用同样逻辑加载itemVersionHistory列表
// ...

// 原有处理逻辑保持不变
foreach (Item myItem in currentItemVersion)
{
    if (myItem.IsGood) 
    {
        var goodItems = itemVersionHistory.Where(x => x.Item_ID == myItem.Item_ID).ToList();                
        foreach (Item itemVersions in goodItems)
        {
            // 执行你的业务逻辑
        }
    }           
}

3. ORM简化方案(如Entity Framework)

如果使用ORM框架,可直接用Skip+Take实现分页:

int rowsPerPage = 4;
var dbContext = new YourDbContext();
int totalItems = dbContext.SampleFruits.Count();
int totalPages = (int)Math.Ceiling(totalItems / (double)rowsPerPage);

List<Item> allItems = new List<Item>();
for (int page = 0; page < totalPages; page++)
{
    var pageItems = dbContext.SampleFruits
                            .OrderBy(f => f.Price)
                            .Skip(page * rowsPerPage)
                            .Take(rowsPerPage)
                            .Select(f => new Item
                            {
                                FruitName = f.FruitName,
                                Price = f.Price
                            })
                            .ToList();
    allItems.AddRange(pageItems);
}

内容的提问来源于stack exchange,提问作者StackTrace

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:05:23