Игнорировать сопоставление одного свойства с Automapper - PullRequest
253 голосов
/ 14 февраля 2011

Я использую Automapper, и у меня есть следующий сценарий: Класс OrderModel имеет свойство ProductName, которого нет в базе данных.Поэтому, когда я пытаюсь выполнить сопоставление с:

Mapper.CreateMap<OrderModel, Orders>(); 

, оно генерирует исключение:

"Следующие 1 свойства в Project.ViewModels.OrderModel не сопоставляются: 'ProductName'

Я прочитал в Wiki для проекций AutoMapper обратный случай (дополнительный атрибут находится в месте назначения, а не в источнике, который фактически является моим случаем)

Как я могуизбежать автоматического создания отображения этого свойства?

Ответы [ 7 ]

411 голосов
/ 14 февраля 2011

От Джимми Богарда: CreateMap<Foo, Bar>().ForMember(x => x.Blarg, opt => opt.Ignore());

Это в одном из комментариев в его блоге .

224 голосов
/ 29 мая 2013

Я, возможно, немного перфекционист; Мне не очень нравится синтаксис ForMember (..., x => x.Ignore ()). Это мелочь, но это важно для меня. Я написал этот метод расширения, чтобы сделать его немного лучше:

public static IMappingExpression<TSource, TDestination> Ignore<TSource, TDestination>(
    this IMappingExpression<TSource, TDestination> map,
    Expression<Func<TDestination, object>> selector)
{
    map.ForMember(selector, config => config.Ignore());
    return map;
}

Может использоваться так:

Mapper.CreateMap<JsonRecord, DatabaseRecord>()
        .Ignore(record => record.Field)
        .Ignore(record => record.AnotherField)
        .Ignore(record => record.Etc);

Вы также можете переписать его для работы с params, но мне не нравится внешний вид метода с множеством лямбд.

75 голосов
/ 16 апреля 2012

Вы можете сделать это:

conf.CreateMap<SourceType, DestinationType>()
   .ForSourceMember(x => x.SourceProperty, y => y.Ignore());
28 голосов
/ 13 февраля 2013

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

public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
    var sourceType = typeof(TSource);
    var destinationType = typeof(TDestination);
    var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType)
        && x.DestinationType.Equals(destinationType));
    foreach (var property in existingMaps.GetUnmappedPropertyNames())
    {
        expression.ForMember(property, opt => opt.Ignore());
    }
    return expression;
}

будет использоваться следующим образом:

Mapper.CreateMap<SourceType, DestinationType>().IgnoreAllNonExisting();

спасибо Can Gencer за подсказку :)

источник: http://cangencer.wordpress.com/2011/06/08/auto-ignore-non-existing-properties-with-automapper/

28 голосов
/ 23 сентября 2011

Теперь есть (AutoMapper 2.0) атрибут IgnoreMap, который я собираюсь использовать вместо беглого синтаксиса, который немного тяжелый ИМХО.

19 голосов
/ 15 июня 2015

При отображении модели представления обратно в модель домена, может быть намного проще просто проверить исходный список членов, а не целевой список членов

Mapper.CreateMap<OrderModel, Orders>(MemberList.Source); 

Теперь моя проверка сопоставления не завершается с ошибкой, требующей еще Ignore() каждый раз, когда я добавляю свойство в мой класс домена.

0 голосов
/ 15 декабря 2015

Привет всем, пожалуйста, используйте это, это работает нормально ... для автоматического картографирования используйте несколько .ForMember в C #

        if (promotionCode.Any())
        {
            Mapper.Reset();
            Mapper.CreateMap<PromotionCode, PromotionCodeEntity>().ForMember(d => d.serverTime, o => o.MapFrom(s => s.promotionCodeId == null ? "date" : String.Format("{0:dd/MM/yyyy h:mm:ss tt}", DateTime.UtcNow.AddHours(7.0))))
                .ForMember(d => d.day, p => p.MapFrom(s => s.code != "" ? LeftTime(Convert.ToInt32(s.quantity), Convert.ToString(s.expiryDate), Convert.ToString(DateTime.UtcNow.AddHours(7.0))) : "Day"))
                .ForMember(d => d.subCategoryname, o => o.MapFrom(s => s.subCategoryId == 0 ? "" : Convert.ToString(subCategory.Where(z => z.subCategoryId.Equals(s.subCategoryId)).FirstOrDefault().subCategoryName)))
                .ForMember(d => d.optionalCategoryName, o => o.MapFrom(s => s.optCategoryId == 0 ? "" : Convert.ToString(optionalCategory.Where(z => z.optCategoryId.Equals(s.optCategoryId)).FirstOrDefault().optCategoryName)))
                .ForMember(d => d.logoImg, o => o.MapFrom(s => s.vendorId == 0 ? "" : Convert.ToString(vendorImg.Where(z => z.vendorId.Equals(s.vendorId)).FirstOrDefault().logoImg)))
                .ForMember(d => d.expiryDate, o => o.MapFrom(s => s.expiryDate == null ? "" : String.Format("{0:dd/MM/yyyy h:mm:ss tt}", s.expiryDate))); 
            var userPromotionModel = Mapper.Map<List<PromotionCode>, List<PromotionCodeEntity>>(promotionCode);
            return userPromotionModel;
        }
        return null;
...