C# AutoMapper:如何以兼容ProjectTo的方式将单个对象映射为单元素列表
解决方案
要实现单个对象到包含该对象的列表的映射,同时兼容IQueryable/ProjectTo,核心是利用AutoMapper内置的集合映射能力,避免直接在映射表达式中创建List实例(这会导致LINQ提供者无法解析)。具体步骤如下:
- 确保已正确配置单个元素的映射(
Dto.TeamMember→TeamMember)。 - 在
Dto.TeamMember→Team的映射中,将TeamMembers字段映射为包含源对象的数组,AutoMapper会自动完成数组到List<TeamMember>的转换,同时保持ProjectTo的表达式可解析性。
修改后的映射配置
class TeamMemberProfile : Profile { public TeamMemberProfile() { // 基础元素映射 this.CreateMap<Dto.TeamMember, TeamMember>(MemberList.None); // 单个对象到Team的映射 this.CreateMap<Dto.TeamMember, Team>(MemberList.None) .ForMember(dest => dest.TeamName, src => src.MapFrom(src => src.TeamName)) // 关键:返回包含源对象的数组,AutoMapper自动映射元素并转为List .ForMember(dest => dest.TeamMembers, src => src.MapFrom(src => new[] { src })); } }
原理说明
- 之前的错误原因:直接使用
new List<TeamMember> { src }时,AutoMapper无法将Dto.TeamMember直接转为TeamMember并生成可被LINQ提供者解析的表达式,因为List的初始化操作无法被翻译成SQL或其他查询语言。 - 改用数组初始化
new[] { src }后,AutoMapper会利用已配置的Dto.TeamMember→TeamMember映射,自动将数组中的每个元素转换,同时将数组转换为List<TeamMember>。这个过程的表达式可以被ProjectTo正确解析,不会破坏IQueryable的查询能力。
额外验证
如果需要更明确地指定集合类型,也可以显式配置数组到列表的映射(不过AutoMapper默认已支持,通常无需额外配置):
this.CreateMap<Dto.TeamMember[], List<TeamMember>>();
内容的提问来源于stack exchange,提问作者Warren Ashcroft
相关产品推荐
相关产品推荐

