如何在LINQ中按多个日期字段的最新值执行OrderByDescending排序?
解决LINQ按最新手术日期排序的问题
我明白你的需求了——要根据原始手术日期+所有已填写的变更日期中的最新值来降序排序,当没有变更日期时就用原始日期。咱们可以通过计算所有相关日期的最大值来实现这个逻辑,下面是具体的修改方案:
方案一:集合过滤取最大值(推荐,逻辑清晰)
这种写法把所有相关日期放在一个集合里,过滤掉空值后取最大值,EF Core 3.0+ 可以直接翻译成SQL执行:
var sortedItems = context.ReservationRequests .Where(s => s.ReservationRequestStatusId.HasValue && s.ReservationRequestStatusId.Value == ReservationRequestStatusId && (Roles.Any(y => s.SubmitterGroupName == y) || s.CreatedBy == currentUserGuid)) .OrderByDescending(x => // 收集原始日期和三个变更日期 new[] { x.ProcedureDate, x.ChangeProcedureDate1, x.ChangeProcedureDate2, x.ChangeProcedureDate3 } .Where(date => date.HasValue) // 过滤掉空的日期字段 .DefaultIfEmpty(x.ProcedureDate) // 如果所有日期都为空, fallback到原始日期 .Max(date => date ?? DateTime.MinValue) // 取最新的日期,处理最后可能的空值 );
逻辑解释:
- 第一步把四个日期字段放进数组,涵盖所有可能的手术日期来源
Where(date => date.HasValue)去掉所有未填写的变更日期(null值)DefaultIfEmpty(x.ProcedureDate)确保即使所有日期都是null,也有一个默认值(和你原来的逻辑对齐)- 最后用
Max取集合里的最大日期,也就是最新的手术日期
方案二:嵌套Max比较(兼容旧版EF)
如果你的EF版本不支持数组操作,可以用嵌套的Max方法逐个比较,逻辑是一样的:
var sortedItems = context.ReservationRequests .Where(s => s.ReservationRequestStatusId.HasValue && s.ReservationRequestStatusId.Value == ReservationRequestStatusId && (Roles.Any(y => s.SubmitterGroupName == y) || s.CreatedBy == currentUserGuid)) .OrderByDescending(x => // 逐层比较取最大值,空日期用DateTime.MinValue忽略 (x.ProcedureDate ?? DateTime.MinValue) .Max(x.ChangeProcedureDate1 ?? DateTime.MinValue) .Max(x.ChangeProcedureDate2 ?? DateTime.MinValue) .Max(x.ChangeProcedureDate3 ?? DateTime.MinValue) );
逻辑解释:
- 把每个空日期替换成
DateTime.MinValue,这样在比较最大值时,空日期会被自动忽略(因为它是最小的日期值) - 逐层调用
Max,最终得到四个日期里的最大值
这两种方案都能满足你的业务需求,你可以根据自己的EF版本选择合适的写法。
内容的提问来源于stack exchange,提问作者HereToLearn_
相关产品推荐
相关产品推荐

