首页 > 解决方案 > 使用 Automapper 从 DTO 属性填充实体类中的列表

问题描述

我对使用 AutoMapper 很陌生,我花了几天时间在谷歌上搜索一个没有运气的解决方案。我正在尝试将如下所示的 DTO 映射到我的实体类,其中包含多个级别的信息(年、季度、季节、期间、周、日)。

这是我的 DTO:

public class CalendarDto
{
    public int Year { get; set; }
    public int Quarter { get; set; }
    public string Season { get; set; }
    public int DayOfWeek { get; set; }
    public string Date { get; set; }
    public int WeekOfYear { get; set; }
    public int DayOfYear { get; set; }
    public int WeekOfPeriod { get; set; }
}

这是我的实体的前两个级别:

    public class Calendar : ICalendar<string>
    {
        public string Id { get; set; }
        public int Year { get; set; }
        public string Date { get; set; }
        public CalendarQuarter Quarters { get; set; }
    }

   public class CalendarQuarter
    {
        public int Year { get; set; }
        public int Quarter { get; set; }
        public string Date { get; set; }
        public List<CalendarSeason> Seasons { get; set; }
    }

如您所见,我从一年到季度、到季节、到时期、到每周和每天都有额外的嵌套级别。我只提供第一个级别,逐个季度,因为我确信一旦我确定了一个级别,其余的将是直截了当的。

我尝试将配置文件设置为从 DTO 分别映射每个类,如下所示,因为所有属性值都匹配。

public class CalendarProfile : Profile
{
    public CalendarProfile()
    {
        CreateMap<CalendarDto, Calendar>().ReverseMap();
        CreateMap<CalendarDto, CalendarQuarter>().ReverseMap();
        CreateMap<CalendarDto, CalendarSeason>().ReverseMap();
        CreateMap<CalendarDto, CalendarPeriod>().ReverseMap();
        CreateMap<CalendarDto, CalendarWeek>().ReverseMap();
        CreateMap<CalendarDto, CalendarDay>().ReverseMap();
    }
}

当我尝试将 DTO 映射到处理程序中的实体时,仅映射了 Calendar 类并且 CalendarQuarters 列表为空。我的理解是配置文件与配置相同,并且在配置文件中创建的所有映射都将在执行 Map 时执行。显然,我错了,我的映射设置不正确,或者两者兼而有之!哈哈

var calendar = _mapper.Map<CalendarDto, Calendar>(parms.Dto);

任何建议将不胜感激。感谢您的帮助!

标签: c#automapper

解决方案


首先要提一下,使用 automapper 可以使映射看起来更容易,但是无法调试代码,并且当您的项目变得很大并且映射不是那么复杂时,您可能会遇到问题(您始终可以显式映射并轻松调试) 这很无聊,所以在你决定使用它之前,最好记住这一点,阅读这篇文章: article1article2

如果使用自动映射器,您应该阅读文档。我认为你需要这样的东西:

CreateMap<Calendar, CalendarDto>().ForMember(dest => dest.Quarters.Quarter, 
                                             opt => opt.Quarter)
                                  .ForMember(dest => dest.Quarters.Quarter.Seasons.Season
                                             opt => opt.Season);

我删除了反向映射,因为我从我的项目中复制了这个并更改了属性,我希望你可以应用到所有属性。当然,您有许多属性,因此您可以链接ForMember和定义所有映射,如果您不这样做,则此映射器仅映射具有相同名称的属性。


推荐阅读