#c# #.net-core #automapper-7
#c# #.net-core #automapper-7
Вопрос:
Я столкнулся с проблемой с моим кодом .NET CORE 2.1 и AutoMapper для сопоставления DTO с DomainModels и наоборот.
Изначально я использую CreateRequest DTO для создания данных, которые сопоставляются с моей моделью домена. По причинам обновления я использую DTO UpdateRequest, который является производным от моего DTO CreateRequest. В моем классе UpdateRequest есть еще несколько свойств, которые также существуют в моем полном классе модели домена.
Теперь я смог воспроизвести странную ошибку при чтении моего объекта модели сразу после того, как он был создан с помощью запроса create. Обновление этой модели чтения с помощью моего UpdateRequest DTO с использованием AutoMapper вызывает следующую проблему: свойство с именем «VersionNumber», похоже, игнорируется, в то время как другие свойства были установлены успешно. Похоже, что AutoMapper сохранил унаследованный класс CreateRequest как единственную существующую карту и использует ее также для отображения производного класса UpdateRequest.
Я воссоздал эту ситуацию в LINQPad и добавил используемый код сюда.
static bool init = false;
void Main()
{
init.Dump("IsInitialized");
if (!init)
{
// Configuration 1
AutoMapper.Mapper.Initialize(cfg => { cfg.CreateMissingTypeMaps = true; cfg.ValidateInlineMaps = false; });
// Configuration 2
// AutoMapper.Mapper.Initialize(cfg =>
// {
// cfg.CreateMap<Bar, Model>();
// // Configuration 2, also define map for the derived type
//// cfg.CreateMap<Foo, Model>();
// });
init = true;
}
// Create model and save db changes
Model created = AutoMapper.Mapper.Map<Model>(new Bar { Name="Bar" });
created.Dump("Created");
// Read model from db
var b = new Model { Name = created.Name, VersionNumber = created.VersionNumber };
// Create derived model to update read model
var f = new Foo { Name = "Foo", VersionNumber = 123 };
// Update entity
var result = AutoMapper.Mapper.Map(f, b);
b.Dump("Updated Bar");
result.Dump("Result = Updated Bar");
}
class Foo : Bar {
public long? VersionNumber {get; set;}
}
class Model {
public string Name {get; set;}
public long VersionNumber {get; set;}
}
class Bar {
public string Name {get;set;}
}
Далее я должен объяснить мою используемую конфигурацию.
Конфигурация 1 была моей первой попыткой просто использовать «динамическую» конфигурацию отображения.
При тестировании этой ошибки использовалась конфигурация 2.
И, наконец, отображение будет работать, только если вы определите оба типа, базовый тип и производную.
Результатом для 1 должен быть «Номер версии» 123, вместо этого он равен 0. То же самое для 2, без его правильного определения. Ожидаемый результат будет получен только при использовании 2 с обоими отображениями. Все три параметра конфигурации работают для свойства «Name».
В LINQPad я ссылался на следующую версию AutoMapper: ….nuget packages automapper 7.0.1 lib netstandard2.0
Я ожидал бы, что при первоначальном сопоставлении динамической конфигурации возникает ошибка или что AutoMapper распознает, что я хочу сопоставить производный тип и, следовательно, должен использовать другую карту.
Комментарии:
1. Динамические отображения работают только в простейших случаях. В вашем случае вы должны установить CreateMissingTypeMaps в значение false и создать все необходимые карты.
2. Это ошибка или известная вещь? Я шокирован тем, что динамическая карта ведет себя так по-разному в зависимости от того, создавали ли вы карту базового класса раньше: gist.github.com/matthiaslischka /…
3. Я создал проблему на github, потому что нахожу такое поведение очень странным: github.com/AutoMapper/AutoMapper/issues/3025