Ответ 1
От Джимми Богарда: CreateMap<Foo, Bar>().ForMember(x => x.Blarg, opt => opt.Ignore());
Я использую Automapper, и у меня есть следующий сценарий: Класс OrderModel имеет свойство "ProductName", которое отсутствует в базе данных. Поэтому, когда я пытаюсь выполнить сопоставление с помощью:
Mapper.CreateMap<OrderModel, Orders>();
Он генерирует исключение:
"Следующие 1 свойства в Project.ViewModels.OrderModel не отображаются: 'ProductName'
Я читал в AutoMapper Wiki for Projections противоположный случай (дополнительный атрибут находится в месте назначения, а не в источнике, который на самом деле мой случай)
Как я могу избежать automapper, чтобы сделать отображение этого свойства?
От Джимми Богарда: CreateMap<Foo, Bar>().ForMember(x => x.Blarg, opt => opt.Ignore());
Возможно, я немного перфекционист; Мне не очень нравится синтаксис 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
, но мне не нравится внешний вид метода с множеством lambdas.
Вы можете сделать это:
conf.CreateMap<SourceType, DestinationType>()
.ForSourceMember(x => x.SourceProperty, y => y.Ignore());
Теперь есть (AutoMapper 2.0) атрибут IgnoreMap
, который я собираюсь использовать, а не беглый синтаксис, который немного тяжелый ИМХО.
Просто для тех, кто пытается сделать это автоматически, вы можете использовать этот метод расширения для игнорирования не существующих свойств в целевом типе:
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/
При сопоставлении модели представления с моделью домена может быть намного проще просто проверять список членов-источников, а не список участников-адресата
Mapper.CreateMap<OrderModel, Orders>(MemberList.Source);
Теперь мое подтверждение сопоставления не прерывается, требуя другого Ignore()
, каждый раз, когда я добавляю свойство в свой класс домена.
Я оценил добавление, добавленное Стивом Рукусом, поэтому я решил добавить еще один метод расширения, основанный на его примере. Надеюсь, это поможет кому-то:
public static IMappingExpression<TSource, TDestination> Map<TSource, TDestination>(
this IMappingExpression<TSource, TDestination> map,
Expression<Func<TSource, object>> src,
Expression<Func<TDestination, object>> dst)
{
map.ForMember(dst, opt => opt.MapFrom(src));
return map;
}
Использование:
Mapper.Initialize(cfg => cfg.CreateMap<UserModel, UserDto>()
.Map(src => src.FirstName + " " + src.LastName, dst => dst.UserName));
Привет всем Пожалуйста, используйте это, чтобы он работал нормально... для автоматического сопоставления используйте несколько .ForMember в С#
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;