使用GroupBy对含List<Category>属性的Product列表分组生成子列表
问题核心原因
你原来的写法存在两个问题:
GroupBy(a => a.Categories)是把整个List<Category>作为分组键,引用类型默认按内存地址匹配,只要不是同一个列表实例就算分类内容完全一致也会被分到不同组,完全不符合需求- 你的需求是允许同一个商品出现在多个分类下,直接对Product集合分组是做不到的,需要先把「1个商品对应N个分类」的结构拆成N条「1个分类对应1个商品」的映射再分组
解决方法
用LINQ的SelectMany方法先展开多对多关联,再按分类分组即可,示例如下:
首先假设你的Category类结构如下(如果你的实际字段不同调整对应属性名即可):
public class Category { public int Id { get; set; } // 分类名用于展示 public string Name { get; set; } }
修正后的业务代码:
StringBuilder ProductList = new StringBuilder(); var categoryGroups = _products // 展开每个商品对应的所有分类,生成「分类+商品」的一对一映射条目 .SelectMany(product => product.Categories.Select(cate => new { CateName = cate.Name, Product = product })) // 按分类名称分组,也可以按cate.Id分组避免重名分类合并的问题 .GroupBy(item => item.CateName, item => item.Product); foreach (var group in categoryGroups) { ProductList.Append($"<p><strong>{group.Key}</strong><br/>"); foreach (var product in group) { ProductList.Append($"{product.Title}<br/>"); } ProductList.Append("</p>"); }
额外说明
- 修正了你原代码里
</p>写在商品循环内的语法错误,避免生成非法的HTML结构 - 如果需要按分类排序,在
GroupBy后追加.OrderBy(g => g.Key)即可 - 如果存在同名但不同ID的分类,把分组键换成
new { cate.Id, cate.Name }即可保证分组准确性
内容的提问来源于stack exchange,提问作者Tim Cadieux
相关产品推荐
相关产品推荐

