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为负数,因此抛出该错误。
解决方法
- 修正运算符优先级:给
PageNumber - 1加上括号,确保先计算页码减1,再乘以每页大小:
.Skip((PageNumber - 1) * PageSize)
- 添加参数校验:为了避免非法参数(比如
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
相关产品推荐
相关产品推荐

