#c# #asp.net-core #automapper #asp.net-core-webapi
Вопрос:
Здравствуйте, ребята, у меня возникли большие проблемы с отображением некоторых моделей с помощью AutoMapper, и я хотел бы знать, не могли бы вы указать мне правильное направление.
У меня есть некоторые сущности, как показано ниже;
public class Camp
{
public int CampId { get; set; }
public string Name { get; set; }
public string Moniker { get; set; }
public Location Location { get; set; }
public DateTime EventDate { get; set; } = DateTime.MinValue;
public int Length { get; set; } = 1;
public ICollection<Talk> Talks { get; set; }
}
public class Talk
{
public int TalkId { get; set; }
public Camp Camp { get; set; }
public string Title { get; set; }
public string Abstract { get; set; }
public int Level { get; set; }
public Speaker Speaker { get; set; }
}
И соответствующие DTO
public class CampModel
{
public string Name { get; set; }
public string Moniker { get; set; }
public DateTime EventDate { get; set; } = DateTime.MinValue;
public int Length { get; set; } = 1;
public string Venue { get; set; }
public string LocationAddress1 { get; set; }
public string LocationAddress2 { get; set; }
public string LocationAddress3 { get; set; }
public string LocationCityTown { get; set; }
public string LocationStateProvince { get; set; }
public string LocationPostalCode { get; set; }
public string LocationCountry { get; set; }
public ICollection<TalkModel> Talks { get; set; }
}
public class TalkModel
{
public int TalkId { get; set; }
public string Title { get; set; }
public string Abstract { get; set; }
public int Level { get; set; }
}
Я хотел использовать automapper на своем контроллере следующим образом:
[Route("api/[controller]")]
public class CampsController : ControllerBase
{
private readonly ICampRepository _repository;
private readonly IMapper _mapper;
public CampsController(ICampRepository repository, IMapper mapper)
{
_repository = repository;
_mapper = mapper;
}
[HttpGet]
public async Task<ActionResult<CampModel[]>> Get(bool includeTalks = false)
{
try
{
var camps = await _repository.GetAllCampsAsync(includeTalks);
var mapper = _mapper.Map<CampModel[]>(camps);
return mapper;
}
catch (Exception e)
{
return StatusCode(StatusCodes.Status500InternalServerError, "Database failure" " Message: " e);
}
}
}
I’m returning the camps on my repository like this:
public async Task<Camp[]> GetAllCampsByEventDate(DateTime dateTime, bool includeTalks = false)
{
_logger.LogInformation($"Getting all Camps");
IQueryable<Camp> query = _context.Camps
.Include(c => c.Location);
if (includeTalks)
{
query = query
.Include(c => c.Talks)
.ThenInclude(t => t.Speaker);
}
// Order It
query = query.OrderByDescending(c => c.EventDate)
.Where(c => c.EventDate.Date == dateTime.Date);
return await query.ToArrayAsync();
}
I already registered my automapper on Startup.Cs
services.AddAutoMapper(typeof(CampProfile).Assembly);
Использование профиля, подобного этому:
public class CampProfile : Profile
{
public CampProfile()
{
this.CreateMap<Camp, CampModel>()
.ForMember(c => c.Venue, o => o.MapFrom(m => m.Location.VenueName))
.ForMember(c => c.Talks, o => o.MapFrom(m => m.Talks))
.ReverseMap();
}
}
Но когда я пытаюсь попасть в свою конечную точку, я получаю следующую ошибку:
Message: AutoMapper.AutoMapperMappingException: Error mapping types.
Mapping types:
Object -> CampModel[]
System.Object -> CoreCodeCamp.Models.CampModel[]
---> AutoMapper.AutoMapperMappingException: Error mapping types.
Mapping types:
Camp -> CampModel
CoreCodeCamp.Data.Camp -> CoreCodeCamp.Models.CampModel
Type Map configuration:
Camp -> CampModel
CoreCodeCamp.Data.Camp -> CoreCodeCamp.Models.CampModel
Destination Member:
Talks
---> AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.
Mapping types:
Talk -> TalkModel
CoreCodeCamp.Data.Talk -> CoreCodeCamp.Models.TalkModel
Что я делаю не так? Я думаю, что проблема связана с public ICollection<Talk> Talks { get; set; }
собственностью. Заранее спасибо
Ответ №1:
Просто добавьте сопоставитель между Talk
и TalkModel
, как показано ниже:
public class CampProfile : Profile
{
public CampProfile()
{
this.CreateMap<Talk, TalkModel>();
this.CreateMap<Camp, CampModel>()
.ForMember(c => c.Venue, o => o.MapFrom(m => m.Location.VenueName))
//.ForMember(c => c.Talks, o => o.MapFrom(m => m.Talks))
.ReverseMap();
}
}
Комментарии:
1.
Talks
Конфигурация не нужна.
Ответ №2:
Из кода, который вы дали выше , вам нужно настроить карту между Talk
и TalkModel
, проверьте вложенные сопоставления в AutoMapper.