C#技术求助:如何用Linq按Model_1分组并解决AutoMapper映射问题?
问题分析与解决方案
首先,你的代码存在两个核心问题:
- 分组键选择错误:你试图直接用
model_2.Model_1(注意你代码里写的是小写model_1,这是笔误,会导致编译错误)作为分组键,但它是IList<Model_1>集合类型。集合默认按引用判断相等性,这不符合实际分组需求,且EF Core通常不支持直接按集合分组。 - AutoMapper映射缺失:错误提示
Create using CreateMap<IGrouping2, GetModel2Dto>说明你后续试图将Linq返回的IGrouping<,>类型映射到GetModel2Dto`,但未配置对应的映射规则。
以下是两种常见场景的正确Linq写法:
场景1:按Model_1的唯一标识(如Id)分组(最常用)
先通过SelectMany将Model_2与它关联的Model_1扁平化,再按Model_1的Id分组:
var groupByResult = from model2 in _context.Model_2 from model1 in model2.Model_1 group model2 by model1.Id into newGroup orderby newGroup.Key select new { Model1Id = newGroup.Key, AssociatedModel2s = newGroup.ToList() };
这种方式返回的是包含分组键和对应Model_2集合的匿名类型,你可以直接用这个类型构造GetModel2Dto,或者配置AutoMapper将该匿名类型映射到Dto,避免IGrouping的映射问题。
场景2:按整个Model_1实体分组
如果确实需要按完整的Model_1实体分组,必须先给Model_1重写Equals和GetHashCode方法,让系统能判断两个Model_1实体是否相等:
public class Model_1 { public int Id { get; set; } public string Name { get; set; } public override bool Equals(object obj) { if (obj is not Model_1 other) return false; // 按业务逻辑判断相等性,这里用Id和Name return Id == other.Id && Name == other.Name; } public override int GetHashCode() { return HashCode.Combine(Id, Name); } }
之后的Linq查询写法:
var groupByResult = from model2 in _context.Model_2 from model1 in model2.Model_1 group model2 by model1 into newGroup orderby newGroup.Key.Id select new { GroupedModel1 = newGroup.Key, AssociatedModel2s = newGroup.ToList() };
额外提示
- 修正代码中的笔误:Model_2类的属性是
public IList<Model_1> Model_1 {get;set;},查询中要使用model2.Model_1(大写开头),否则会编译失败。 - 避免直接返回
IGrouping类型给AutoMapper,尽量在Linq的select阶段构造与Dto结构匹配的对象,简化映射配置。
内容的提问来源于stack exchange,提问作者Rahul Parab
相关产品推荐
相关产品推荐

