AutoMapper игнорирует непроизводные свойства при динамической или неполной конфигурации отображения

#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