使用OrderBy按日期排序列表无效,求助排查问题原因
问题分析与解决
你的排序不生效主要有两个核心问题:
1. 字符串格式的日期无法正确排序
你把CreatedAt(DateTime类型)转成了"dd/MM/yyyy"格式的字符串存储,而字符串排序是按字典序来的,和实际日期的时间顺序完全不符。举个例子:
- 10月5日转成字符串是
"05/10/2024" - 9月20日转成字符串是
"20/09/2024"
字符串比较时,"05..."会被判定为小于"20...",但实际日期前者更晚,这就导致排序结果完全不符合预期。
2. 排序方向搞反了
你用了OrderBy和ThenBy,这两个方法是升序排序(从旧日期到新日期),但你的需求是从最新到最旧,应该用降序的OrderByDescending和ThenByDescending。
修复方案
最优方案:保留DateTime类型字段排序
修改RegisteredRequest类,新增两个DateTime类型的字段(比如RequestCreatedAt和ItemCreatedAt),不要直接转成字符串存储日期:
// 调整RegisteredRequest类定义 public class RegisteredRequest { public DateTime RequestCreatedAt { get; set; } public string RequestNum { get; set; } public DateTime ItemCreatedAt { get; set; } public string ItemNum { get; set; } // 保留原有的字符串日期字段用于展示(如果需要) public string RequestDate => RequestCreatedAt.ToString("dd/MM/yyyy"); public string ItemDate => ItemCreatedAt.ToString("dd/MM/yyyy"); // 构造函数调整 public RegisteredRequest(DateTime requestCreatedAt, string requestNum, DateTime itemCreatedAt, string itemNum) { RequestCreatedAt = requestCreatedAt; RequestNum = requestNum; ItemCreatedAt = itemCreatedAt; ItemNum = itemNum; } }
然后修改循环中的赋值逻辑,排序时直接用DateTime字段:
var Items = await this.ItemsRepository.GetAllAsync(expression); var report = new List<RegisteredRequest>(); // 这里注意原代码写的是RegisteredOrders,应该是笔误 foreach (var item in Items) { var request = await this.RequestRepository.GetOneAsync(x => !x.Deleted && x.Id == item.requestId); report.Add(new RegisteredRequest( requestCreatedAt: request.CreatedAt, requestNum: request.RequestCode, itemCreatedAt: item.CreatedAt, itemNum: item.ItemCode )); } // 用降序排序,从最新到最旧 var orderReport = report.OrderByDescending(x => x.RequestCreatedAt) .ThenByDescending(x => x.ItemCreatedAt); return orderReport.ToList();
备选方案:如果必须用字符串日期排序
如果因为某些原因必须保留字符串格式的日期,可以在排序时把字符串转回DateTime再比较:
using System.Globalization; // ... 前面代码不变 ... var orderReport = report.OrderByDescending(x => DateTime.ParseExact(x.requestDate, "dd/MM/yyyy", CultureInfo.InvariantCulture)) .ThenByDescending(x => DateTime.ParseExact(x.itemDate, "dd/MM/yyyy", CultureInfo.InvariantCulture)); return orderReport.ToList();
这种方式要注意:如果字符串格式不匹配会抛出异常,而且性能比直接用DateTime排序差。
内容的提问来源于stack exchange,提问作者PHP
相关产品推荐
相关产品推荐

