如何使用 AutoMapper 从多个对象映射单个对象?

How to map a single object from multiple ones, using AutoMapper?

资产可用性

public class AssetAvailabilityDto
{
    public int Id { get; set; }
    public int AssetId { get; set; }
    public int CalendarId { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
}

资产

public class AssetDto
{
    public int Id { get; set; }
    public int CategoryId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public bool IsActive { get; set; }
    public int OwnedBy { get; set; }
    public DateTime LastModifiedAt { get; set; }
}

预订时间表

public class BookingScheduleDto
{
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

}

容纳他们的目的地

public class AssetInformationDto
{
    public int AssetId { get; set; }
    public int CategoryId { get; set; }
    public string AssetName { get; set; }
    public string AssetDescription { get; set; }
    public bool AssetIsActive { get; set; }
    public int AssetOwnedBy { get; set; }
    public DateTime AssetLastModifiedAt { get; set; }
    // End of Assets
    public int AvailabilityId { get; set; }
    public DateTime AvailabilityStartDate { get; set; }
    public DateTime AvailabilityEndDate { get; set; }
    // End of Availability

    public List<DateTime> BookingStartDate { get; set; } = new List<DateTime>();
    public List<DateTime> BookingEndDate { get; set; } = new List<DateTime>();
    // End of Booking schedule
}

映射发生的地方

        AssetInformationDto information = new AssetInformationDto();
        AssetDto asset = _assetService.GetAssetById(id);
        AssetAvailabilityDto assetAvailability = _assetService.GetAssetAvailabilityByAssetId(id);
        IEnumerable<BookingScheduleDto> schedule = _assetService.GetAssetBookingSchedule(id, true);
        information = _mapper.Map<AssetInformationDto>(asset);
        information = _mapper.Map<AssetInformationDto>(assetAvailability);
        information = _mapper.Map<AssetInformationDto>(schedule);

AutoMapper的配置

 CreateMap<AssetDto, AssetInformationDto>()
            .ForMember(dest => dest.AssetName, opt => opt.MapFrom(src => src.Name))
            .ForMember(dest => dest.AssetDescription, opt => opt.MapFrom(src => src.Description))
            .ForMember(dest => dest.AssetLastModifiedAt, opt => opt.MapFrom(src => src.LastModifiedAt))
            .ForMember(dest => dest.AssetIsActive, opt => opt.MapFrom(src => src.IsActive))
            .ForMember(dest => dest.AssetOwnedBy, opt => opt.MapFrom(src => src.OwnedBy))
            .ForMember(dest => dest.AssetId, opt => opt.MapFrom(src => src.Id))
            .ForAllOtherMembers(m => m.Ignore());
        CreateMap<AssetAvailabilityDto, AssetInformationDto>()
            .ForMember(dest => dest.AvailabilityStartDate, opt => opt.MapFrom(src => src.StartDate))
            .ForMember(dest => dest.AvailabilityEndDate, opt => opt.MapFrom(src => src.EndDate))
            .ForMember(dest => dest.AvailabilityId, opt => opt.MapFrom(src => src.Id))
            .ForAllOtherMembers(m => m.Ignore());
        CreateMap<IEnumerable<BookingScheduleDto>, AssetInformationDto>().AfterMap((s, d) =>
        {
            foreach (var item in s)
            {
                d.BookingStartDate.Add(item.StartDate);
                d.BookingEndDate.Add(item.EndDate);
            }
        }).ForAllOtherMembers(m => m.Ignore());

这是在 ASP.NET Core 2.2 项目上完成的,因此为什么 AutoMapper 总是注入依赖注入(_mapper 是注入的对象)

这里分享的post是解决上述问题的方法,通过制作一个函数"EntityMapper"并稍微修改它以接受注入的_mapper对象,但我'我想学习替代解决方案。

这不是可以通过简单地配置 AutoMapper 来实现吗? 也许它不起作用的原因是我的配置写得不好。

这里的问题是,在每个映射对象之后,(在每个信息之后 = ...)先前分配的属性都恢复为其类型的默认值。这就是为什么我在配置映射完成方式的相应 class 中包含 ForAllOtherMembers.Ignore()

我一直在寻找的是 Mapper.Map(TSource, TDestination) 的用法(由于依赖注入,在我的例子中 Mapper 将是 _mapper。)

它执行从源对象到现有目标对象的映射。

我之前使用的方法 (Mapper.Map<TDestination>(TSource)) 执行从源对象到 目标对象的映射。


之前的代码:

    AssetInformationDto information = new AssetInformationDto();
    AssetDto asset = _assetService.GetAssetById(id);
    AssetAvailabilityDto assetAvailability = _assetService.GetAssetAvailabilityByAssetId(id);
    IEnumerable<BookingScheduleDto> schedule = _assetService.GetAssetBookingSchedule(id, true);
    information = _mapper.Map<AssetInformationDto>(asset);
    information = _mapper.Map<AssetInformationDto>(assetAvailability);
    information = _mapper.Map<AssetInformationDto>(schedule);

解决我问题的代码

    AssetInformationDto information;
    AssetDto asset = _assetService.GetAssetById(id);
    AssetAvailabilityDto assetAvailability =
    _assetService.GetAssetAvailabilityByAssetId(id);
    IEnumerable<BookingScheduleDto> schedule =
    _assetService.GetAssetBookingSchedule(id, true);
    information = _mapper.Map<AssetInformationDto>(asset);
    _mapper.Map(assetAvailability, information);
    _mapper.Map(schedule, information);