web-dev-qa-db-ja.com

AutoMapperを使用して1つのオブジェクトをオブジェクトのリストにマップすることは可能ですか?

これらは私のクラスです:

public class EventLog {
        public string SystemId { get; set; }
        public string UserId { get; set; }
        public List<Event> Events { get; set; }
}

public class Event {
        public string EventId { get; set; }
        public string Message { get; set; }
}

public class EventDTO {
        public string SystemId { get; set; }
        public string UserId { get; set; }
        public string EventId { get; set; }
        public string Message { get; set; }
}

基本的に、ネストされたリストを持つ単一のオブジェクトから、ネストされたリストと親オブジェクトの値を持つオブジェクトのリストに移動する必要があります。これはAutoMapperで実行できますか?イベントリストを簡単にマップし、EventDTOオブジェクトのリストを取得して、手動でSystemIdとUserIdを設定できることを理解しています。AutoMapperに処理を任せると非常に便利です。

28
noocyte

これらの3つのマッピングには、1つのカスタムコンバーターが必要です。

Mapper.CreateMap<Event, EventDTO>(); // maps message and event id
Mapper.CreateMap<EventLog, EventDTO>(); // maps system id and user id
Mapper.CreateMap<EventLog, IEnumerable<EventDTO>>()
      .ConvertUsing<EventLogConverter>(); // creates collection of dto

したがって、EventからEventDTOへのマッピングとEventLogからEventDTOへのマッピングを構成すると、カスタムコンバーターで両方を使用できます。

class EventLogConverter : ITypeConverter<EventLog, IEnumerable<EventDTO>>
{
    public IEnumerable<EventDTO> Convert(ResolutionContext context)
    {
        EventLog log = (EventLog)context.SourceValue;
        foreach (var dto in log.Events.Select(e => Mapper.Map<EventDTO>(e)))
        {
            Mapper.Map(log, dto); // map system id and user id
            yield return dto;
        }
    }
}

NBuilder を使用したサンプルコード:

var log = new EventLog {
    SystemId = "Skynet",
    UserId = "Lazy",
    Events = Builder<Event>.CreateListOfSize(5).Build().ToList()
};

var events = Mapper.Map<IEnumerable<EventDTO>>(log);
34