AutoMapper如何实现一对多实体到一对一视图模型的映射?
AutoMapper 一对多转一对一映射实现方案
场景支持说明
AutoMapper 完全支持这类映射需求,你可以通过自定义字段映射规则,从源对象的集合属性中按需提取值,映射到目标对象的单个字段。
具体实现步骤
1. 配置映射规则
继承AutoMapper的Profile类编写映射配置,同名属性TeamName会自动映射,只需手动配置PersonName的提取逻辑即可,示例如下:
using AutoMapper; using System.Linq; public class MappingProfile : Profile { public MappingProfile() { CreateMap<Team, TeamDetailsViewModel>() // 自定义PersonName的映射逻辑,此处示例取集合第一个成员的名字,空值做兜底处理 .ForMember(dest => dest.PersonName, opt => opt.MapFrom(src => src.Member?.FirstOrDefault()?.PersonName ?? string.Empty)); } }
如果你有其他业务提取逻辑,比如要取符合特定条件的成员姓名,只需修改
MapFrom内的逻辑即可,比如筛选姓名为"李四"的成员:src.Member?.FirstOrDefault(p => p.PersonName == "李四")?.PersonName ?? string.Empty
2. 注册AutoMapper服务
如果是ASP.NET Core项目,在Program.cs中注册映射配置即可:
builder.Services.AddAutoMapper(typeof(MappingProfile));
3. 调用映射
注入IMapper接口后直接调用映射方法即可:
// 假设team是从数据库查询到的Team实体实例 var viewModel = _mapper.Map<TeamDetailsViewModel>(team);
扩展场景:单个Team映射为多个ViewModel
如果你需要把Team下的每个Person都生成对应的TeamDetailsViewModel(即一个Team对应N个ViewModel),可以用如下配置实现:
public MappingProfile() { CreateMap<Person, TeamDetailsViewModel>() .ForMember(dest => dest.TeamName, opt => opt.MapFrom((src, dest, _, context) => context.Items["TeamName"]?.ToString() ?? string.Empty)); }
调用时传入TeamName参数:
var viewModels = team.Member.Select(p => _mapper.Map<TeamDetailsViewModel>(p, opts => opts.Items["TeamName"] = team.TeamName) ).ToList();
内容的提问来源于stack exchange,提问作者Hai
相关产品推荐
相关产品推荐

