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

标签 c# asp.net-core automapper

Assets 可用性

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; }
}

Assets

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 总是注入(inject)依赖注入(inject)(_mapper 是注入(inject)的对象)

帖子在这里分享 https://stackoverflow.com/a/38257912/11272124是上述问题的一个解决方案,方法是创建一个函数“EntityMapper”并稍微修改它以接受注入(inject)的 _mapper 对象,但我想学习另一种解决方案。

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

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

最佳答案

我一直在寻找的是 Mapper.Map(TSource, TDestination) 的用法(由于依赖注入(inject),在我的例子中 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);

关于c# - 如何使用 AutoMapper 从多个对象映射单个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57398432/

相关文章:

c# - 如何使文本框只接受货币格式输入?

c# - 如何处理 TDD 中的接口(interface)过度使用?

c# - ASP.NET 4.5 或替代框架中的 OpenIdDict?

c# - 为什么 AutoMapper 不能正确格式化我的日期?

c# - 如何在 AutoMapper 配置文件类中注入(inject)服务?

c# - 在两条路径之间创建相对路径

c# - WPF - MVVM - 从 View 模型返回可绑定(bind)控件模板

asp.net-core - Autofac 依赖解析异常

asp.net-core - Asp.net core 1.1 本地化,不会改变文化

c# - Automapper 可以映射分页列表吗?