如何在AM/PM/24小时制下实现支持同起止日期的日期范围查询
问题原因
DateTime类型默认包含时分秒,你传入纯日期参数时,参数的时间部分默认是00:00:00,而数据库存储的CreatedOn字段通常带有业务发生的具体时间。当两个参数为同一天时,条件x.CreatedOn >= '2021-10-20' && x.CreatedOn <= '2021-10-20'实际只匹配2021-10-20 00:00:00整的记录,当天其他时间的记录都会被过滤。
解决方案
提供两种兼容多场景的实现方式,任选一种即可:
方案1:统一按日期维度匹配(推荐,适配EF/EF Core,可直接翻译为SQL)
直接在查询条件中提取CreatedOn的日期部分和参数的日期部分匹配,无需额外处理入参:
public ResponseDTO<IQueryable<LabRequestForLabOrderDTO>> GetApprovedLabRequestsQueryable(DateTime defaultFromD, DateTime defaultToD) { var resp = ResponseBuilder.Build<IQueryable<LabRequestForLabOrderDTO>>(); var reqs = this.labRequestRepository.GetAllActive().Where(x => x.IsActive && x.TrxStatus == 1 && x.InvoiceStatus == "Approved" // 仅修改日期判断部分,统一取日期维度匹配 && x.CreatedOn.Date >= defaultFromD.Date && x.CreatedOn.Date <= defaultToD.Date) .Select(x => new LabRequestForLabOrderDTO { Clinic = x.Clinic, LabOrderCreated = x.LabOrderCreated, InvoiceStatus = x.InvoiceStatus, CreatedOn = x.CreatedOn }).AsQueryable(); resp.AddSuccessResult(reqs); return resp; }
方案2:调整结束参数的时间范围(适配所有ORM,无需修改查询字段逻辑)
在查询前先把结束日期的时间部分调整为当天的最大刻度,原有比较逻辑无需修改:
public ResponseDTO<IQueryable<LabRequestForLabOrderDTO>> GetApprovedLabRequestsQueryable(DateTime defaultFromD, DateTime defaultToD) { var resp = ResponseBuilder.Build<IQueryable<LabRequestForLabOrderDTO>>(); // 处理结束日期:取日期部分加1天再减1个计时最小单位,得到当天的最大时间点 DateTime processedToD = defaultToD.Date.AddDays(1).AddTicks(-1); var reqs = this.labRequestRepository.GetAllActive().Where(x => x.IsActive && x.TrxStatus == 1 && x.InvoiceStatus == "Approved" && x.CreatedOn >= defaultFromD.Date && x.CreatedOn <= processedToD) .Select(x => new LabRequestForLabOrderDTO { Clinic = x.Clinic, LabOrderCreated = x.LabOrderCreated, InvoiceStatus = x.InvoiceStatus, CreatedOn = x.CreatedOn }).AsQueryable(); resp.AddSuccessResult(reqs); return resp; }
两种方案都可以同时支持跨日期范围查询、单日查询两种场景。
内容的提问来源于stack exchange,提问作者Chathuranga Ranasingha
相关产品推荐
相关产品推荐

