Automapper: карта многих ко многим - PullRequest
0 голосов
/ 30 сентября 2019

У меня есть следующая модель:

public class Device
{
    public string DeviceId { get; set; }
    public string DeviceName { get; set; }

    private ICollection<TagDevice> _tagDevices;
    public virtual ICollection<TagDevice> TagDevices { get => _tagDevices ?? (_tagDevices = new List<TagDevice>()); protected set => _tagDevices = value; }

}

public class Tag : BaseEntity
{
    public string Name { get; set; }

    private ICollection<TagDevice> _tagDevices;
    public virtual ICollection<TagDevice> TagDevices { get => _tagDevices ?? (_tagDevices = new List<TagDevice>()); protected set => _tagDevices = value; }
}


public class TagDevice
{
    public int TagId { get; set; }
    public string DeviceId { get; set; }

    public virtual Tag Tag { get; set; }
    public virtual Device Device { get; set; }
}

У меня есть класс DTO:

public class TagDisplayDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime? UpdatedAt { get; set; }
    public int TimesUsed { get; set; }
    public int CarrierId { get; set; }
}

public class DeviceDisplayDto
{
    public string DeviceId { get; set; }
    public string DeviceName { get; set; }

    public List<TagDisplayDto> Tags { get; set; }    
}

Теперь я хочу создать отображение для DeviceDisplayDto с заполненными тегами:

        CreateMap<Device, DeviceDisplayDto>()
            .ForMember(d => d.Tags, opt => opt.MapFrom(s => s.TagDevices...))
            ;

TagDevices является коллекцией, а не типом Tag, каждый элемент коллекции имеет свойство с типом Tag. Как его создать?

1 Ответ

1 голос
/ 01 октября 2019

Вы можете использовать Select() на коллекции TagDevice s, чтобы преобразовать ее в список TagDisplayDto s:

CreateMap<Device, DeviceDisplayDto>()
    .ForMember(deviceDisplayDto => deviceDisplayDto.Tags, options =>
        options.MapFrom(device => device.TagDevices.Select(tagDevice => new TagDisplayDto
        {
            CarrierId = 123,                // TODO
            CreatedAt = DateTime.UtcNow,    // TODO
            Id = tagDevice.TagId,
            Name = tagDevice.Tag.Name,
            TimesUsed = 0,                  // TODO
            UpdatedAt = DateTime.UtcNow,    // TODO
        }).ToList()));

Я пометил некоторые свойства как TODO, так как не знаю всегомодель, которую вы используете, и некоторые свойства отсутствуют. Вам нужно будет заполнить его самостоятельно. По крайней мере, этот код должен помочь вам начать работу.

Edit # 1

Как и предполагал Люциан, еще лучшим решением является полное использование функциональности AutoMapper. Создайте сопоставления между двумя моделями:

  • от Device до DeviceDisplayDto
  • от TagDevice до TagDisplayDto
CreateMap<Device, DeviceDisplayDto>()
    .ForMember(deviceDisplayDto => deviceDisplayDto.Tags, options =>
        options.MapFrom(device => device.TagDevices));
CreateMap<TagDevice, TagDisplayDto>()
    .ForMember(tagDisplayDto => tagDisplayDto.CarrierId, options =>
        options.MapFrom(tagDevice => 123))                          // TODO
    .ForMember(tagDisplayDto => tagDisplayDto.CreatedAt, options =>
        options.MapFrom(tagDevice => DateTime.UtcNow.AddDays(-60))) // TODO
    .ForMember(tagDisplayDto => tagDisplayDto.Id, options =>
        options.MapFrom(tagDevice => tagDevice.TagId))
    .ForMember(tagDisplayDto => tagDisplayDto.Name, options =>
        options.MapFrom(tagDevice => tagDevice.Tag.Name))
    .ForMember(tagDisplayDto => tagDisplayDto.TimesUsed, options =>
        options.MapFrom(tagDevice => 0))                            // TODO
    .ForMember(tagDisplayDto => tagDisplayDto.UpdatedAt, options =>
        options.MapFrom(tagDevice => DateTime.UtcNow));             // TODO

ТоКстати, логика отображения, определенная выше, является многоразовой. Как и в моем первом решении, вам придется самостоятельно заполнить свойства, отмеченные TODO.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...