Automapper - как применить конфигурацию ForMember на глубоком уровне - PullRequest
0 голосов
/ 08 апреля 2019

пытаюсь освоить asp.NetCore 2.2. Я пытаюсь настроить простой одностраничный сайт. Я столкнулся с проблемой с Automapper, где Mappinng вручную с использованием forMember () работает на верхнем уровне для CreateMap<Listing, ListingSearchResultsDto>().ForMember(ListingPhotosUrl), но не на нижнем уровне. У меня есть другое отображение CreateMap<User, UserDetailsDto>(), где user содержит объект Mylistings типа Listing. Mylistings правильно автоматически сопоставляется с ListingSearchResultsDto, но ручная настройка CreateMap<Listing, ListingSearchResultsDto>().ForMember(ListingPhotosUrl) не применяется.

Я пытался CreateMap<User, UserDetailsDto>().Formember(dest.Mylistings.ListingPhotosUrl,src.Mylistings.Photos.Url), но, похоже, это невозможно.

Я тоже пробовал это-> Но не повезло

            var config = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<User, UserDetailsDto>();
                cfg.CreateMap<Listing, ListingSearchResultsDto>()
                .ForMember(dest => dest.ListingPhotosUrl, opt =>
            {
                opt.MapFrom(src => src.Photos.FirstOrDefault(p => p.IsMain).Url);
            });

            });

            var mapper = config.CreateMapper();

Код:

AutoMappperProfiles

 public AutoMapperProfiles()
        {
            CreateMap<Listing, ListingSearchResultsDto>()
            .ForMember(dest => dest.ListingPhotosUrl, opt =>
            {
                opt.MapFrom(src => src.Photos.FirstOrDefault(p => p.IsMain).Url);
            });           


            CreateMap<User, UserDetailsDto>();

            CreateMap<ListingPhoto, ListingPhotosDetailedDto>();
        }

Пользователь

    public class User
    {
        public int Id { get; set; }
        public string Username { get; set; }

        public ICollection<Listing> MyListings { get; set; }
    }

UserDetailsDto

public class UserDetailsDto
    {
        public int Id { get; set; }
        public string Username { get; set; }

        public ICollection<ListingSearchResultsDto> MyListings { get; set;}
     }

Листинг

        public int id { get; set; }
        public string Category { get; set; }
        public string Title { get; set; }

        public ICollection<ListingPhoto> Photos { get; set; }

ListingSearchResultsDto

    public class ListingSearchResultsDto
    {
        public int id { get; set; }
        public string Title { get; set; }
        public string ListingPhotosUrl { get; set; }                    
    }

Я использую CreateMap<Listing, ListingSearchResultsDto>().Formember(des,src), чтобы вручную сопоставить свойство назначения ListingPhotosUrl. У меня есть другое отображение CreateMap<User, UserDetailsDto>(). Внутри User & UsedetailsDto классов у меня есть объекты с именем MyListings типов ICollection<Listing> и ICollection<ListingSearchResultsDto> соответственно. MyListings объект автоматически сопоставлен правильно, но ListingPhotosUrl ручное сопоставление не применяется. CreateMap<Listing,ListingSearchResultsDto>.Formember(des,src)) ручное отображение работает на верхнем уровне, но не на более глубоком уровне внутри CreateMap<User, UserDetailsDto>(), есть ли способ исправить это? спасибо

1 Ответ

0 голосов
/ 08 апреля 2019

ИСПРАВЛЕНО - Automapper работал нормально. Проблема в Entity Framework DbContext. Я не включил фотографии в качестве связанных данных в метод EF Core для загрузки данных ПОЛЬЗОВАТЕЛЯ GETUSER(). Он работал с методом EF Core для загрузки LISTING GetListing(), потому что у меня было включение для фотографий Include(p => p.Photos).

После добавления .ThenInclude(p => p.Photos) в GetUser() фотографии были возвращены с данными ПОЛЬЗОВАТЕЛЯ, и автоматическое сопоставление успешно сопоставило данные пользователя, и ListingPhotosUrl ручное сопоставление было успешно применено.

Базовая структура Entity Framework DbContext:

public async Task<User> GetUser(int id)
{
    var user = await _context.Users
        .Include(a => a.Avatar)
        .Include(l => l.MyListings)
            .ThenInclude(p => p.Photos)
                .FirstOrDefaultAsync(u => u.Id == id);

    return user;
}

public async Task<Listing> GetListing(int id)
{
    var listing = await _context.Listings
        .Include(p => p.Photos)
        .FirstOrDefaultAsync(l => l.id == id);

    return listing;
}
...