#c# #model #automapper #viewmodel #object-object-mapping
#c# #Модель #automapper #viewmodel #объект-сопоставление объектов
Вопрос:
Я пытаюсь изучить asp.NETCore 2.2. Я пытаюсь настроить простой одностраничный сайт. Я столкнулся с проблемой с Automapper, когда ручное отображение с использованием 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
amp; UsedetailsDto
classes у меня есть объекты, вызываемые MyListings
типами ICollection<Listing>
и ICollection<ListingSearchResultsDto>
соответственно. MyListings
объект автоматически отображается правильно, но ListingPhotosUrl
ручное отображение не применяется. CreateMap<Listing,ListingSearchResultsDto>.Formember(des,src))
ручное сопоставление работает на верхнем уровне, но не на более глубоком уровне внутри CreateMap<User, UserDetailsDto>()
, можно ли это исправить? Спасибо
Комментарии:
1. Правильно ли настроен DI? Проверьте документы .
Ответ №1:
ИСПРАВЛЕНО — Automapper работал нормально. Проблема в Entity Framework DbContext. Я не включил фотографии в качестве связанных данных в метод ядра EF для загрузки пользовательских данных GETUSER()
. Он работал с основным методом EF для загрузки списка GetListing()
, потому что у меня было включение для фотографий Include(p => p.Photos)
.
После добавления .ThenInclude(p => p.Photos)
GetUser()
фотографии были возвращены с пользовательскими данными, и automapper успешно сопоставил пользовательские данные, и 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;
}