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

EF Core 6分页报错:OFFSET不能为负数,求排查与解决方法

EF Core 6分页报错:OFFSET must not be negative的原因及解决方法

你在使用EF Core 6和.NET Core实现分页时,代码如下:

public async Task<IEnumerable<CommentResponse>> GetCommentOfPostAsync(Guid PostId, int PageNumber, int PageSize)
    => await _context.Comments
                    .Include(comment => comment.User)
                    .OrderBy(comment => comment.CommentId)
                    .Select(
                        data => new CommentResponse
                        {
                            CommentId = data.CommentId,
                            UserId = data.UserId,
                            Avatar = data.User.Avatar,
                            CommentText = data.CommentText,
                            Username = data.User.Username,
                            Created = data.Created
                        }
                    )
                    .Skip(PageNumber - 1 * PageSize)
                    .Take(PageSize)
                    .ToListAsync();

当传入的PageSize大于1时,触发错误:

Npgsql.PostgresException (0x80004005): 2201X: OFFSET must not be negative

错误原因

这是运算符优先级导致的问题:C#中乘法(*)的优先级高于减法(-),所以PageNumber - 1 * PageSize会先计算1 * PageSize,再用PageNumber减去这个结果。

比如当PageNumber = 1、PageSize = 2时,实际计算的是1 - (1*2) = -1,Skip(-1)会被EF Core转换成PostgreSQL的OFFSET -1,而PostgreSQL不允许OFFSET为负数,因此抛出该错误。

解决方法

  1. 修正运算符优先级:给PageNumber - 1加上括号,确保先计算页码减1,再乘以每页大小:
.Skip((PageNumber - 1) * PageSize)
  1. 添加参数校验:为了避免非法参数(比如PageNumber < 1、PageSize <= 0)导致的其他问题,建议在方法开头添加校验逻辑:
public async Task<IEnumerable<CommentResponse>> GetCommentOfPostAsync(Guid PostId, int PageNumber, int PageSize)
{
    if (PageNumber < 1)
        throw new ArgumentOutOfRangeException(nameof(PageNumber), "页码必须大于等于1");
    if (PageSize <= 0)
        throw new ArgumentOutOfRangeException(nameof(PageSize), "每页数量必须大于0");

    return await _context.Comments
                    .Include(comment => comment.User)
                    .OrderBy(comment => comment.CommentId)
                    .Select(
                        data => new CommentResponse
                        {
                            CommentId = data.CommentId,
                            UserId = data.UserId,
                            Avatar = data.User.Avatar,
                            CommentText = data.CommentText,
                            Username = data.User.Username,
                            Created = data.Created
                        }
                    )
                    .Skip((PageNumber - 1) * PageSize)
                    .Take(PageSize)
                    .ToListAsync();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 16:36:22