如何使用LINQ按嵌套的作者姓名属性对Book列表进行排序
问题核心原因
- 排序逻辑错误:
OrderBy方法要求传入的委托返回一个可比较的基础类型(比如string、int等),你原来的写法返回的是排序后的作者序列,该序列未实现IComparable接口,无法作为排序比较的依据。 - 现有代码存在两处隐藏问题:
- 反序列化时泛型参数写为
List<Item>,但你定义的实体类是Book,会导致编译报错 - JSON中作者字段的键是
Author,但Book类中的对应属性名是Authors,字段名不匹配会导致反序列化后Authors属性为null
- 反序列化时泛型参数写为
修复方案
第一步:修正反序列化逻辑
两种方式解决字段不匹配问题:
- 方式1:修改
Book类的属性名和JSON键一致:
public class Book { public int Id { get; set; } public string Title { get; set; } // 把属性名从Authors改成Author public List<Author> Author { get; set; } }
- 方式2:给属性加
JsonProperty特性指定映射键:
public class Book { public int Id { get; set; } public string Title { get; set; } [JsonProperty("Author")] public List<Author> Authors { get; set; } }
之后修正反序列化代码:
List<Book> books; using (StreamReader sr = new StreamReader(Server.MapPath("..."))) { // 把泛型参数从Item改成Book books = JsonConvert.DeserializeObject<List<Book>>(sr.ReadToEnd()); }
第二步:实现按作者姓名排序
根据你的业务场景选对应写法:
场景1:每本书只有1个作者(符合你给出的JSON示例情况)
直接取第一个作者的姓名作为排序依据即可,内置空值容错:
var list = books.OrderBy(b => b.Authors.FirstOrDefault()?.Name).ToList();
场景2:每本书可能有多个作者,按第一作者姓名排序
先把当前书的作者按姓名排序,取第一个的姓名作为整本书的排序依据:
var list = books.OrderBy(b => b.Authors?.OrderBy(a => a.Name).FirstOrDefault()?.Name ).ToList();
场景3:需要按所有作者的姓名综合排序
可以把所有作者姓名排序后拼接为字符串,作为排序依据:
var list = books.OrderBy(b => string.Join(",", b.Authors?.Select(a => a.Name).OrderBy(n => n) ?? Enumerable.Empty<string>()) ).ToList();
内容的提问来源于stack exchange,提问作者MarkQA
相关产品推荐
相关产品推荐

