如何用LINQ对List<Person>按District和Level多分组并保留原字段
解决按District和Level分组并返回List的LINQ查询问题
首先,先明确你的需求:要对已有的Person列表先按District、再按Level分组,最终结果还是List<Person>类型,不能用var和匿名类型,还要保留所有字段。
首先,你的Person类是这样的:
public class Person { public string ID {get; set;} public string Name {get; set;} public string District {get; set;} public string Level {get; set;} }
因为不能用匿名类型作为分组键,我们需要先定义一个专门的分组键类GroupKey,记得重写Equals和GetHashCode方法,这样LINQ的GroupBy才能正确识别相同的分组:
public class GroupKey { public string District { get; set; } public string Level { get; set; } // 重写Equals确保分组键的对比逻辑正确 public override bool Equals(object obj) { if (obj is GroupKey otherKey) { return District == otherKey.District && Level == otherKey.Level; } return false; } // 重写GetHashCode保证相同键的哈希值一致 public override int GetHashCode() { return HashCode.Combine(District, Level); } }
接下来就是完整的LINQ查询代码,完全符合你的要求(不用var、不用匿名类型,返回List<Person>):
// 假设这是你的已赋值Person列表 List<Person> sourcePersons = GetYourPersonList(); // 替换成你的实际数据源 // 按District+Level分组,再展开为List<Person> List<Person> groupedPersons = sourcePersons .GroupBy<Person, GroupKey>(p => new GroupKey { District = p.District, Level = p.Level }) // 如果需要按District和Level排序分组顺序,加上下面两行 .OrderBy<IGrouping<GroupKey, Person>, string>(g => g.Key.District) .ThenBy<IGrouping<GroupKey, Person>, string>(g => g.Key.Level) .SelectMany<IGrouping<GroupKey, Person>, Person>(g => g) .ToList();
代码解释:
GroupBy<Person, GroupKey>:明确指定输入类型是Person,分组键类型是我们定义的GroupKey,避免使用var。OrderBy和ThenBy:确保分组的顺序是先按District排序,同一District内再按Level排序,如果不需要排序可以直接去掉这两行。SelectMany:把每个分组里的Person元素展开成一个连续的序列,最终通过ToList()转换成List<Person>,完美保留所有字段。
这样写就完全满足你的所有要求啦!
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

