如何使用Entity Framework为ASP.NET Core Web API添加日期过滤功能
基于EF Core实现日期过滤+分页的简便方案
核心思路
利用EF Core的IQueryable延迟执行特性,动态拼接过滤条件,最终只会生成包含过滤、排序、分页的单条SQL查询,既简洁又高效。
步骤实现
调整API端点与参数
把原来的路由参数page改为查询参数(同时支持日期过滤参数),就能兼容/api/Request?page=1&Initialdate=2022/09/06&FinalDate=2022/09/10的请求格式。修改控制器方法
以下是完整的优化代码:[HttpGet] public async Task<ActionResult<RequestResponse>> Get( int page = 1, DateTime? Initialdate = null, DateTime? FinalDate = null) { // 参数合法性校验 if (page < 1) { return BadRequest("页码不能小于1"); } if (Initialdate.HasValue && FinalDate.HasValue && Initialdate > FinalDate) { return BadRequest("开始日期不能晚于结束日期"); } var pageResults = 2; // 构建基础查询 IQueryable<Requests> query = _context.Requests; // 添加日期过滤条件 if (Initialdate.HasValue) { // 匹配开始日期及之后的记录(包含当天0点) query = query.Where(r => r.RequestDate >= Initialdate.Value); } if (FinalDate.HasValue) { // 匹配结束日期当天的最后一刻,避免漏掉当天的记录 var endOfDay = FinalDate.Value.Date.AddDays(1).AddTicks(-1); query = query.Where(r => r.RequestDate <= endOfDay); } // 计算过滤后的总页数 var totalCount = await query.CountAsync(); var pageCount = (int)Math.Ceiling(totalCount / (double)pageResults); // 执行排序、分页查询 var requests = await query .OrderBy(x => x.RequestDate) .Skip((page - 1) * pageResults) .Take(pageResults) .ToListAsync(); var response = new RequestResponse { Requests = requests, CurrentPage = page, Pages = pageCount, TotalCount = totalCount // 可选:返回总记录数,方便前端展示 }; return Ok(response); }
关键细节说明
- 延迟执行:所有
Where、OrderBy、Skip、Take操作都会被EF Core翻译成SQL的对应子句,最终只执行一次数据库查询,性能最优。 - 日期边界处理:针对
FinalDate处理成当天的最后一刻(比如2022/09/10 23:59:59.9999999),避免只匹配到当天0点之前的记录,漏掉当日请求。 - 参数灵活性:日期参数设为
Nullable<DateTime>,用户可只传开始日期、只传结束日期,或都不传(返回全部分页数据)。 - 参数校验:提前校验页码和日期合法性,避免无效查询。
请求示例
- 查询第1页,过滤2022年9月6日至9月10日的记录:
GET https://localhost:7171/api/Request?page=1&Initialdate=2022/09/06&FinalDate=2022/09/10 - 查询第2页,只过滤2022年9月6日之后的记录:
GET https://localhost:7171/api/Request?page=2&Initialdate=2022/09/06 - 查询全部分页数据(无过滤):
GET https://localhost:7171/api/Request?page=1
内容的提问来源于stack exchange,提问作者Smuk
相关产品推荐
相关产品推荐

