如何根据OrderingLetter类型条件排序Lambda查询返回的列表?
混合规则排序实现方案
针对你的需求——数字类型的OrderingLetter按数值排序,非数字按字符串排序,提供两种实现方式:
方式一:数据库端排序(EF Core支持)
利用EF Core对int.TryParse的SQL转换支持,先生成临时排序字段,完成排序后再返回目标DTO结构:
var dicWords = _context.dicWords .Select(p => new { // 保留目标DTO的所有字段 Id = p.Id, OrderingLetter = p.OrderingLetter, Word = p.Word, // 生成排序用的辅助字段 IsNumeric = int.TryParse(p.OrderingLetter, out _), NumericValue = int.TryParse(p.OrderingLetter, out int num) ? num : int.MaxValue }) .OrderBy(p => p.IsNumeric) // 数字项排在前面 .ThenBy(p => p.NumericValue) // 数字按数值大小排序 .ThenBy(p => p.OrderingLetter) // 非数字按原字符串排序 .Select(p => new WordsDicDto // 转换回目标DTO { Id = p.Id, OrderingLetter = p.OrderingLetter, Word = p.Word }) .ToList();
方式二:内存端排序(兼容EF6或不支持TryParse转SQL的场景)
先将数据加载到内存中,再通过自定义排序逻辑处理:
var dicWords = _context.dicWords .Select(p => new WordsDicDto { Id = p.Id, OrderingLetter = p.OrderingLetter, Word = p.Word }) .ToList() .OrderBy(p => { if (int.TryParse(p.OrderingLetter, out int num)) { // 数字项:用0作为分组键(确保排在前面),补前导零避免字符串排序异常(如"10"排在"2"前) return (0, num.ToString("D10")); } else { // 非数字项:用1作为分组键(排在后面),按原字符串排序 return (1, p.OrderingLetter); } }) .ToList();
注:内存排序里的
D10是将数字转换为10位固定长度的字符串,比如数字2会变成"0000000002",确保数值小的数字在字符串排序中也排在前面。
内容的提问来源于stack exchange,提问作者nnmmss
相关产品推荐
相关产品推荐

