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

.NET Core Web API分页接收用户数据时如何持久化数据?

解决方案

方案1:基于批次ID+临时存储(推荐,支持多实例部署)

核心思路是让客户端先发起同步初始化请求获取唯一批次ID,后续每一页数据提交时都携带该ID。服务端以批次ID为标识,将各页数据暂存到Redis、数据库临时表等分布式存储中,收到最后一页时汇总该批次下的所有数据统一处理。

实现步骤:

  1. 添加同步初始化接口生成批次ID:
[HttpPost("InitUserSync")]
public async Task<IActionResult> InitUserSync()
{
    var batchId = Guid.NewGuid().ToString();
    // 可选:初始化批次记录到数据库,用于跟踪同步状态、超时清理
    await _tempBatchRepo.CreateBatchAsync(batchId);
    return Ok(new { BatchId = batchId });
}
  1. 修改原接口,接收批次ID并暂存数据:
[HttpPost("SyncroniseUsers")]
public async Task<IActionResult> SyncroniseUsers([FromBody] UserPageDataWithBatch userPageData)
{
    // 验证批次ID有效性
    var validBatch = await _tempBatchRepo.IsBatchValidAsync(userPageData.BatchId);
    if (!validBatch)
    {
        return BadRequest("无效批次ID,请先初始化同步");
    }

    // 将当前页数据存入临时存储(示例用Redis,也可替换为数据库临时表)
    await _redisClient.ListRightPushAsync($"user_sync:{userPageData.BatchId}", 
        JsonSerializer.Serialize(userPageData.UserData));

    if(userPageData.IsLastPage)
    {
        // 汇总该批次所有数据
        var allPageJson = await _redisClient.ListRangeAsync($"user_sync:{userPageData.BatchId}");
        var allUsers = allPageJson.Select(json => JsonSerializer.Deserialize<User[]>(json))
                                 .SelectMany(u => u)
                                 .ToList();

        // 执行计算并写入正式数据库
        await _userRepo.BulkSaveUsersAsync(allUsers);

        // 清理临时数据
        await _redisClient.KeyDeleteAsync($"user_sync:{userPageData.BatchId}");
        await _tempBatchRepo.MarkBatchCompletedAsync(userPageData.BatchId);

        return Ok(new { Message = "同步完成", TotalUsers = allUsers.Count });
    }

    return Ok(new { Message = "当前页数据已接收" });
}

// 扩展请求模型,增加批次ID字段
public class UserPageDataWithBatch : UserPageData
{
    public string BatchId { get; set; }
}
  1. Windows服务调用流程:
    • 先调用InitUserSync获取批次ID
    • 逐页提交数据,每次携带该批次ID
    • 最后一页设置IsLastPage=true

方案2:使用ASP.NET Core Session(仅单实例部署场景)

如果API是单实例部署,可以利用Session暂存数据。需先配置Session服务:

配置Session:

在Program.cs中添加:

builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromHours(1); // 设置足够完成同步的超时时间
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});

// 注册Session中间件(需放在UseRouting之后,UseEndpoints之前)
app.UseSession();

修改接口:

[HttpPost("SyncroniseUsers")]
public async Task<IActionResult> SyncroniseUsers([FromBody] UserPageData userPageData)
{
    // 从Session获取已暂存的用户列表,不存在则初始化
    var storedUsers = HttpContext.Session.Get<List<User>>("SyncUsers") ?? new List<User>();
    storedUsers.AddRange(userPageData.UserData);

    if(userPageData.IsLastPage)
    {
        // 执行计算并保存到数据库
        await _userRepo.BulkSaveUsersAsync(storedUsers);
        // 清理Session数据
        HttpContext.Session.Remove("SyncUsers");
        return Ok(new { Message = "同步完成", TotalUsers = storedUsers.Count });
    }

    // 将更新后的列表存入Session
    HttpContext.Session.Set("SyncUsers", storedUsers);
    return Ok(new { Message = "当前页数据已接收" });
}

// Session序列化/反序列化扩展方法
public static class SessionExtensions
{
    public static void Set<T>(this ISession session, string key, T value)
    {
        session.SetString(key, JsonSerializer.Serialize(value));
    }

    public static T Get<T>(this ISession session, string key)
    {
        var value = session.GetString(key);
        return value == null ? default : JsonSerializer.Deserialize<T>(value);
    }
}

注意:Session依赖Cookie,Windows服务调用时需确保HttpClient启用Cookie支持(如设置HttpClientHandler.UseCookies = true)。

方案3:直接批量提交(网络带宽允许时)

如果客户端与API之间带宽充足,可将数千条数据打包为一个请求提交,避免分页逻辑。但数据量过大(如超过100MB)时,仍建议使用批次ID方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 13:05:12