Câu hỏi Có thể sử dụng AutoMapper để ánh xạ một đối tượng vào danh sách các đối tượng?


Đây là những lớp của tôi:

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

Về cơ bản tôi cần phải đi từ một đối tượng duy nhất, với một danh sách lồng nhau, vào một danh sách các đối tượng với các giá trị từ danh sách lồng nhau và đối tượng cha. Điều này có thể được thực hiện trong AutoMapper không? Tôi nhận ra rằng tôi có thể dễ dàng ánh xạ danh sách Sự kiện và nhận danh sách các đối tượng EventDTO và sau đó đặt SystemId và UserId theo cách thủ công, nó sẽ rất thuận tiện để cho phép AutoMapper xử lý nó cho tôi.


19
2017-08-07 06:22


gốc




Các câu trả lời:


Bạn sẽ cần ba bản đồ này với một trình chuyển đổi tùy chỉnh:

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

Do đó bạn đã định cấu hình ánh xạ từ Event đến EventDTO và từ EventLog đến EventDTO bạn có thể sử dụng cả hai công cụ này trong trình chuyển đổi tùy chỉnh:

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

Mã mẫu với NBuilder:

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

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

26
2017-08-07 07:12



Làm thế nào để làm việc foreach mà không cần sử dụng cuộc gọi Mapper.Map toàn cầu? Tôi có các phiên bản động cơ khác nhau. - Beachwalker
@Beachwalker, thêm một nhà xây dựng để thực hiện chuyển đổi loại của bạn mà lấy ví dụ động cơ của bạn như là một tham số. Nếu bạn đang sử dụng vùng chứa DI như AutoFac và bạn đã đăng ký các công cụ lập bản đồ khác nhau, thì bạn chỉ cần đăng ký bộ chuyển đổi mới của mình và vùng chứa sẽ giải quyết thông số động cơ mới cho bạn. Ngay cả khi bạn không sử dụng DI, tuy nhiên, một tham số constructor là con đường để đi. Bạn sẽ chỉ phải truyền tham số bất cứ khi nào bạn xây dựng một thể hiện của trình biến đổi kiểu mới. - bugged87