Устранение неполадок и отладка C#
Проблема с AutoMapper заняла у меня несколько часов
Недавно передо мной встала простая задача: преобразовать некоторые существующие модели данных в новые модели, определенные в сторонней библиотеке.
По согласованию с командой для этой работы будет использоваться AutoMapper. Быстро я закончил большинство из них, но застрял на очень простом.
Существующая модель Period
, которая определяется как
И соответствующая модель данных в сторонней библиотеке выглядит так
Как видим, поля Start
и End
абсолютно одинаковы:
- одинаковые имена свойств
- одинаковые типы недвижимости
Таким образом, код сопоставления должен быть простым и понятным.
К сожалению, тест не пройден, с сообщениями об ошибках ниже:
Error mapping types. Mapping types: Period -> Period MyWork.Model.Period -> Library.Model.Period Type Map configuration: Period -> Period MyWork.Model.Period -> Library.Model.Period Destination Member: Library.Model.Period.Void .ctor(Library.Model.FhirDateTime, Library.Model.FhirDateTime).parameter start
ЧТО?!
В сообщении об ошибке говорится, что произошел сбой на члене Start
. Впрочем, это так просто!
Подождите, давайте попробуем проигнорировать член Start
и ожидать, что он выйдет из строя на End
.
CreateMap<MyWork.Model.Period, Library.Model.Period>() .ForMember(d => d.Start, opt => opt.Ignore());
К сожалению, снова происходит сбой на члене Start
с точно такими же сообщениями об ошибках!!!
Я попытался
- карта
Start
явно... те же ошибки! - карта
StartElement
вручную... те же ошибки! - игнорировать всех участников! Извините, те же ошибки!
Я сошел с ума от такой задачи, которая кажется такой легкой.
Ладно, успокойся.
Я должен снова прочитать сообщения об ошибках. И, нашел эту строку:
Destination Member: Library.Model.Period.Void .ctor(Library.Model.FhirDateTime, Library.Model.FhirDateTime).parameter start
Подожди, ctor
это… Конструктор!
Скажем, он пытался создать объект с помощью этого конструктора
вместо того, что без параметров
а затем было обнаружено, что заданные параметры являютсястроками, но НЕ FhirDateTime
ИТАК, НЕ ПРОШЛО.
Решение простое: просто используйте ConstructUsing
, чтобы указать, какой конструктор следует использовать.
CreateMap<MyWork.Model.Period, Library.Model.Period>() .ConstructUsing(x => new Library.Model.Period());
Теперь он работает, как и ожидалось.
После размещения запроса на слияние я проверил официальную документацию AutoMapper и нашел причину: Constructor Mapping
То есть, если параметры конструктора соответствуют элементам, по умолчанию будет использоваться сопоставленный конструктор.
В документе также упоминается, как его отключить (подробности см. по ссылке ниже).