Подтвердить что ты не робот

Как игнорировать все элементы назначения, кроме тех, которые отображаются?

Есть ли способ сделать это? У нас есть SummaryDto, который отображает три разных типа, и когда мы создаем карту для каждого типа, реквизиты, которые не отображаются, вызывают ошибку. В сводке dto имеется около 35 атрибутов. Использовать опцию Ignore() для каждого из них - слишком большая проблема. Есть глобальное игнорирование? Что-то вроде

CreateMap<Source,Target>()
   .IgnoreAllUnmapped();
4b9b3361

Ответ 1

Это работает для меня:

public static class MappingExpressionExtensions
{
    public static IMappingExpression<TSource, TDest> IgnoreAllUnmapped<TSource, TDest>(this IMappingExpression<TSource, TDest> expression)
    {
        expression.ForAllMembers(opt => opt.Ignore());
        return expression;
    }
}

Поскольку ForAllMembers возвращает void, вызов ForAllMembers(o => o.Ignore()) без этого метода расширения не будет работать. Мы хотим сохранить выражение отображения доступным для последующего отображения:

CreateMap<Source, Destination>()
            .IgnoreAllUnmapped()
            .ForMember(d => d.Text, o => o.MapFrom(s => s.Name))
            .ForMember(d => d.Value, o => o.MapFrom(s => s.Id));

Ответ 2

Я слишком долго боролся с этим, или, по крайней мере, проблема, подобная этому. У меня был класс с множеством свойств (около 30), и я только хотел отобразить около 4 из них. Кажется сумасшедшим добавить 26 игнорируемых утверждений (особенно, когда это означает, что будущие изменения в классе означают необходимость их обновления!)

Наконец-то я обнаружил, что могу сказать AutoMapper игнорировать все, а затем явно добавить те, которые мне нужны.

// Create a map, store a reference to it in a local variable
var map = CreateMap<Source,Target>();

// Ignore all members
map.ForAllMembers(opt => opt.Ignore());

// Add mapping for P1
map.ForMember(dest => dest.P1, opt => opt.MapFrom( src => src.P1));

// Add other mappings...
map.ForMember(dest => dest.P2, opt => opt.MapFrom( src => src.P2));
map.ForMember(dest => dest.P3, opt => opt.MapFrom( src => src.P3));
map.ForMember(dest => dest.P4, opt => opt.MapFrom( src => src.P4));

Вам будет прощено думать, что вы можете просто сделать это (но не потому, что он не будет компилироваться):

// This won't compile
CreateMap<Source,Target>()
   .ForAllMembers(opt => opt.Ignore())
   .ForMember(dest => dest.P1, opt => opt.MapFrom( src => src.P1));

Причина, по которой это не работает, заключается в том, что метод ForAllMembers() не поддерживает свободный стиль цепочки (по крайней мере, в текущей версии 2.0).

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

Ответ 3

Чтобы избежать явного указания отображаемых свойств, вы можете использовать IgnoreAllNonExisting. Он игнорирует любые свойства назначения, которые не имеют отображаемых свойств источника.

Ответ 4

Попробуйте использовать .ConvertUsing() в вашем случае, например.

CreateMap<Source,Target>()
 .ConvertUsing(converter=> new Target(){
P1 = converter.P1,
....
});

Итак, вы можете описать все свойства, которые вы хотите иметь в своем объекте, другие будут проигнорированы.

Ответ 5

Метод расширения, который позволяет свободно использовать синтаксис метода ForAllMembers:

public static IMappingExpression<TSource, TDestination> IgnoreAllMembers<TSource, TDestination>(
    this IMappingExpression<TSource, TDestination> expression
    )
{
    expression.ForAllMembers(opt => opt.Ignore());
    return expression;
}

Использование:

Вызов IgnoreAllMembers должен быть до вызова ForMember.

        CreateMap<LocationRevision, Dto.LocationAddressMap>()
            .IgnoreAllMembers()
            .ForMember(m => m.LocationId, opt => opt.MapFrom(src => src.Id))
            ;