LINQ关联查询结果展平实现及链式语法写法咨询
LINQ关联查询结果展平与链式语法实现方案
嘿,刚好我之前也碰到过类似的需求,这就给你拆解这两个问题的解决方案!
1. 如何实现结果展平(避免手动逐个映射字段)
如果你不想手动敲所有字段的映射关系,最省心且性能友好的方式是用AutoMapper的ProjectTo方法——它能自动把关联表的属性投影到平级的目标类型,而且是在数据库层面执行查询,不会额外拉取冗余数据。
具体步骤:
- 先定义一个DTO类(也可以用匿名类型,但DTO更适合后续维护),包含你需要的所有平级字段:
public class ItemDto { public int ItemId { get; set; } public int ItemTypeId { get; set; } public string ItemCategory { get; set; } public string ItemTypeName { get; set; } // 其他需要的字段都按这个格式添加 }
- 配置AutoMapper的映射规则(同名属性会自动匹配,不用手动一一对应):
var mapperConfig = new MapperConfiguration(cfg => { cfg.CreateMap<Item, ItemDto>(); cfg.CreateMap<ItemType, ItemDto>(); }); var mapper = mapperConfig.CreateMapper();
- 最后在查询中用
ProjectTo完成平级投影:
var items = _context.Items .Join(_context.ItemTypes, i => i.ItemTypeId, it => it.ItemTypeId, (i, it) => new {i, it}) .ProjectTo<ItemDto>(mapperConfig) .AsQueryable();
这样返回的结果就是完全平级的结构,JSON输出自然符合你的期望。
如果你不想引入第三方库,也可以用反射动态构建匿名类型,但这种方式不仅繁琐,还可能导致EF Core无法解析表达式,只能把数据全拉到内存中处理,所以更推荐用AutoMapper方案。
2. 用链式方法语法实现查询
当然可以!把你原来的查询表达式转成链式语法非常直观,下面分两种场景给你示例:
方式一:结合AutoMapper(推荐)
就是上面已经用到的链式写法,再明确贴出来:
var items = _context.Items .Join( inner: _context.ItemTypes, outerKeySelector: item => item.ItemTypeId, innerKeySelector: itemType => itemType.ItemTypeId, resultSelector: (item, itemType) => new { Item = item, ItemType = itemType } ) .ProjectTo<ItemDto>(mapper.ConfigurationProvider) .AsQueryable();
方式二:手动投影(适合字段较少的场景)
如果你愿意手动列出字段,链式语法的手动投影写法如下:
var items = _context.Items .Join( _context.ItemTypes, i => i.ItemTypeId, it => it.ItemTypeId, (i, it) => new { i.ItemId, i.ItemTypeId, it.ItemCategory, it.ItemTypeName // 其他需要的字段依次添加即可 } ) .AsQueryable();
这种写法返回的匿名类型本身就是平级结构,JSON输出会直接是你想要的格式。
内容的提问来源于stack exchange,提问作者mateoc15
相关产品推荐
相关产品推荐

