AutoMapper: Как отобразить только совпадающие имена свойств и игнорировать все остальные? - PullRequest
0 голосов
/ 04 мая 2018

Я новичок в AutoMapper и использую версию 6.2.2. Я пытаюсь сопоставить модель представления с сущностью (также используя Entity Framework). Я хочу обновить только те свойства, которые существуют как в модели представления, так и в объекте. Сущность имеет другие навигационные свойства и связанные объекты, которые не являются частью исходной модели представления. В настоящее время я получаю сообщение об ошибке, что у меня есть несопоставленные свойства целевого объекта. И моя viewmodel, и entity имеют более 40 свойств, поэтому я не хочу явно добавлять каждое из них на карту.

Вот мой код:

Карта:

public static void RegisterMaps()
{
    AutoMapper.Mapper.Initialize(config =>
    {
                    config.CreateMap<EditApplicationViewModel, Application>();

    });

}

Я также пробовал следующее, но получаю ту же ошибку:

config.CreateMap<EditApplicationViewModel, Application>(MemberList.source);

Контроллер:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(EditApplicationViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        Application application = _applicationService.GetById(viewModel.ApplicationId);

        application = Mapper.Map(viewModel, application);
    }
}

Сообщение об ошибке:

InnerException: HResult = -2146233088 Сообщение = не найдены участники. Просмотрите типы и членов ниже. Добавить пользовательское выражение сопоставления, игнорировать, добавить пользовательское выражение распознаватель или измените тип источника / назначения. конструктор, добавьте c-аргумент без аргументов, добавьте необязательные аргументы или отобразите все параметры конструктора ================================================== ======== String -> Пользователь (список получателей) System.String -> . . ***. Entity.User (Список участников назначения)

Не отображенные свойства: удалено - очень длинный список связанных объектов и недвижимость в пункте назначения

   Source=AutoMapper
   StackTrace:
        at lambda_method(Closure , EditApplicationViewModel , Application , ResolutionContext )

UPDATE:

Я также попробовал следующую карту. Я не получаю никаких ошибок, но ни одно из свойств источника не обновляется в месте назначения.

config.CreateMap<EditApplicationViewModel, Application>().ForAllOtherMembers(opts=>opts.Ignore());

Ответы [ 3 ]

0 голосов
/ 04 мая 2018

Возможно, все ваши свойства в обеих моделях не имеют одинаковых имен. Для разных свойств имени вы можете использовать следующий пример:

var source = new Source();

void ConfigureMap(IMappingOperationOptions<Source, Dest> opt) {
    opt.ConfigureMap()
       .ForMember(dest => dest.Value, m => m.MapFrom(src => src.Value))
};

var dest = Mapper.Map<Source, Dest>(source, ConfigureMap);

Где для каждого нового несоответствия имени свойства вы определяете новое .ForMember...

0 голосов
/ 07 мая 2018

Мне удалось решить мою проблему, и это не имело ничего общего с игнорированием свойств, которые не совпадали по названию между источником и местом назначения. Похоже, что поведение AutoMapper по умолчанию уже игнорирует эти свойства по умолчанию.

Сообщение об ошибке очень обманчиво:

  InnerException: 
       HResult=-2146233088
       Message=
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
==========================================================
String -> User (Destination member list)
System.String -> ***.***.***.entities.User (Destination member list)

Фактическая причина моей проблемы - несоответствие типов. У меня есть строковое свойство в модели представления под названием CreatedByUser. У меня также было свойство навигации в моей сущности под названием CreatedByUser типа User.

Мне пришлось явно игнорировать это свойство в CreateMap.

 config.CreateMap<EditApplicationViewModel, Application>()
                    .ForMember(d => d.CreatedByUser, opt => opt.Ignore());

Никаких других директив не требовалось игнорировать любые другие свойства, которых не было ни в источнике, ни в месте назначения.

Опять же, сообщение об ошибке, которое я получил, "Не найдены не найденные участники". через меня Фактической проблемой было несоответствие типов.

0 голосов
/ 04 мая 2018

Вы можете использовать функцию IgnoreUnMapped ().

          config.CreateMap<EditApplicationViewModel, Application>().IgnoreUnMapped();
...