如何用AutoMapper将Axis对象映射为含Country的DTO
解决AutoMapper映射内嵌Country对象的方案
1. 准备工作:确认Country实体与仓储
首先你需要有对应的Country实体类(假设结构如下),以及能通过ID获取Country的仓储接口:
public class Country { public short CountryId { get; set; } public string? CountryName { get; set; } public string? AreaCode { get; set; } } // 仓储接口示例 public interface ICountryRepository { Task<Country?> GetByIdAsync(short countryId); }
在你的Handler类中注入这个仓储:
private readonly IAxisRepository _axisRepository; private readonly ICountryRepository _countryRepository; private readonly IMapper _mapper; public GetAxisByIdQueryHandler(IAxisRepository axisRepository, ICountryRepository countryRepository, IMapper mapper) { _axisRepository = axisRepository; _countryRepository = countryRepository; _mapper = mapper; }
2. 配置AutoMapper映射规则
创建继承自Profile的映射配置类,定义实体到DTO的映射关系:
using AutoMapper; public class AxisMappingProfile : Profile { public AxisMappingProfile() { // 基础映射:Country实体 → CountryResponseDto CreateMap<Country, CountryResponseDto>(); // 核心映射:Axis实体 → GetAxisByIdResponseDto CreateMap<Axis, GetAxisByIdResponseDto>() // 自定义Country属性的映射逻辑,从AutoMapper上下文获取传入的Country对象 .ForMember(dest => dest.Country, opt => opt.MapFrom((src, _, __, context) => context.Mapper.Map<CountryResponseDto>(context.Items["Country"]))); } }
在项目启动类(如Program.cs)中注册AutoMapper和这个Profile:
// .NET 6+ 示例 builder.Services.AddAutoMapper(typeof(AxisMappingProfile));
3. 修改Handler方法,获取Country并完成映射
在Handle方法中,获取Axis后根据Axis.CountryId获取对应Country,再通过AutoMapper上下文传递对象完成映射:
public async Task<BaseResponse<GetAxisByIdResponseDto>> Handle(GetAxisByIdQuery request, CancellationToken cancellationToken) { BaseResponse<GetAxisByIdResponseDto> response = new BaseResponse<GetAxisByIdResponseDto>(); try { Axis axis = await _axisRepository.FindAxisId(request.AxisId); if (axis is null) { response.IsSuccess = false; response.Message = GlobalMessages.MESSAGE_QUERY_EMPTY; return response; } // 根据Axis的CountryId获取对应的Country实体 Country? country = await _countryRepository.GetByIdAsync(axis.CountryId); // 映射时通过Options传递Country对象到AutoMapper上下文 response.Data = _mapper.Map<GetAxisByIdResponseDto>(axis, opt => { if (country != null) { opt.Items["Country"] = country; } }); response.IsSuccess = true; response.Message = GlobalMessages.MESSAGE_QUERY; } catch (SqlException ex) { response.IsSuccess = false; response.Message = ex.Message; } catch (Exception ex) { response.IsSuccess = false; response.Message = GlobalMessages.MESSAGE_EXCEPTION; WatchLogger.Log(ex.Message); } return response; }
4. 注意事项
- 你的期望返回结果里有拼写错误:
cuntry应改为country,默认序列化会将DTO的Country属性转为小驼峰country,与正确字段名匹配。 - 若
Country可能不存在,需处理country == null的情况,此时DTO的Country会为null,可根据业务需求添加默认值或提示逻辑。 - 如果你使用Entity Framework Core,也可以给
Axis实体添加Country导航属性,查询时用Include(a => a.Country)加载关联数据,AutoMapper会自动映射嵌套对象,无需手动传递上下文,但需调整实体类和查询逻辑。
内容的提问来源于stack exchange,提问作者Ing. Jose Valera
相关产品推荐
相关产品推荐

