Мне нужно отобразить объект модели, поступающий из API, на мой фактический объект сущности на DbContext
.Он используется при создании нового машинного объекта с помощью действия POST.
Как всегда, я создал простую карту для исходных / целевых объектов.В этом случае мы рассматриваем исходный объект как модель API, а целевой объект как сущность.Также модель имеет только подмножество свойств сущности.
Типы источника / назначения
// Destination (entity on DbContext)
public class Machine
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string MnmConfiguration { get; set; }
public MachineBootStatus Status { get; set; }
public long MachineDriverId { get; set; }
public MachineDriver MachineDriver { get; set; }
public string DriverConfiguration { get; set; }
public string DriverStatus { get; set; }
}
// Source (from API controller)
public class MachineCreateModel
{
public string Name { get; set; }
public string Description { get; set; }
public string MnmConfiguration { get; set; }
public long MachineDriverId { get; set; }
}
Конфигурация отображения
public class DomainProfile : Profile
{
public DomainProfile()
{
//CreateMap<MachineCreateModel, Machine>();
// Update 2019/01/30 with proposed solution
CreateMap<MachineCreateModel, Machine>(MemberList.Source);
}
}
Я использую контейнер Unity DIи конфигурация AutoMapper такова:
container = new UnityContainer();
// ... some other configurations...
container.RegisterType<IMapper, Mapper>(new InjectionConstructor(new MapperConfiguration(cfg => cfg.AddProfile<DomainProfile>())));
Версия
Использование AutoMapper v8.0.0.
Ожидаемое поведение
Я ожидаю получить простоеавтоматическое сопоставление без ошибок, поскольку моя исходная модель - это только подмножество свойств целевой модели с такими же именами.
Фактическое поведение
Я получаю эту ошибку о несопоставленных свойствах, когда попадаю в эту строкус кодом:
Machine entity = Mapper.Map<Machine>(request.Machine);
[14:08:34.363 8 2e62361a INF] Creating new machine: TEST M1
[14:08:36.205 8 bd577466 ERR] An unhandled exception has occurred while executing the request.
AutoMapper.AutoMapperConfigurationException:
Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters
=================================================================================================
AutoMapper created this type map for you, but your types cannot be mapped using the current configuration.
MachineCreateModel -> Machine (Destination member list)
MyApplication.Dcs.Application.Models.MachineCreateModel -> MyApplication.Dcs.Domain.Entities.Machine (Destination member list)
Unmapped properties:
Id
Status
MachineDriver
DriverConfiguration
DriverStatus
at AutoMapper.ConfigurationValidator.AssertConfigurationIsValid(IEnumerable`1 typeMaps)
at lambda_method(Closure , MachineCreateModel , Machine , ResolutionContext )
at lambda_method(Closure , Object , Object , ResolutionContext )
at AutoMapper.Mapper.AutoMapper.IMapper.Map[TDestination](Object source)
at MyApplication.Dcs.Application.Commands.MachineCreateCommandHandler.Handle(MachineCreateCommand request, CancellationToken cancellationToken) ..Commands\MachineCreateCommand.cs:line 28
Примечание
В моем решении у меня много проектов, и 3 из них используют AutoMapper (одна и та же версия для всех).Есть 3 различных файла DomainProfile.cs
(по 1 для каждого проекта) с необходимыми сопоставлениями.В других классах 2 DomainProfile
у меня есть некоторые ручные отображения (см. Пример ниже), потому что мне нужно «перевести» объект с итальянскими именами свойств в другой с английскими именами свойств.Таким образом, для каждого сопоставления объектов есть много строк, таких как:
CreateMap<ArticleCreateUpdateModel, Articoli>()
.ForMember(d => d.Categoria, opt => opt.MapFrom(src => src.Category))
.ForMember(d => d.CodiceArticolo, opt => opt.MapFrom(src => src.Code))
.ForMember(d => d.Descrizione, opt => opt.MapFrom(src => src.Description))
.ForMember(d => d.Famiglia, opt => opt.MapFrom(src => src.Family))
.ForMember(d => d.Note, opt => opt.MapFrom(src => src.Note))
...
Я не знаю, обязывает ли меня использование этих ручных элементов сопоставления для одного или нескольких классов DomainProfile
всегда объяснять все последующие отображения, даже если они должны быть простыми, как в этом примере.