如何忽略标记为虚拟的所有属性
我正在使用virtual
关键字来获取EF延迟加载的一些属性。 我有一个案例,在将源映射到目标时,应该从AutoMapper中忽略我的模型中标记为virtual
所有属性。
是否有自动方式可以实现此目的,还是应该手动忽略每个成员?
您可以创建映射扩展并使用它:
namespace MywebProject.Extensions.Mapping { public static class IgnoreVirtualExtensions { public static IMappingExpression IgnoreAllVirtual( this IMappingExpression expression) { var desType = typeof(TDestination); foreach (var property in desType.GetProperties().Where(p => p.GetGetMethod().IsVirtual)) { expression.ForMember(property.Name, opt => opt.Ignore()); } return expression; } } }
用法:
Mapper.CreateMap
inquisitive
的答案很好,但是当从数据模型到服务模型执行某些映射并且应该忽略源类型的虚拟成员时,它可以针对现实生活使用进行扩充。
此外,如果类型实现某些接口,那么这些属性将显示为虚拟,因此必须添加!IsFinal
条件以删除这些误报虚拟属性。
public static class AutoMapperExtensions { public static IMappingExpression IgnoreAllDestinationVirtual(this IMappingExpression expression) { var desType = typeof(TDestination); foreach (var property in desType.GetProperties().Where(p => p.GetGetMethod().IsVirtual && !p.GetGetMethod().IsFinal)) { expression.ForMember(property.Name, opt => opt.Ignore()); } return expression; } public static IMappingExpression IgnoreAllSourceVirtual(this IMappingExpression expression) { var srcType = typeof(TSource); foreach (var property in srcType.GetProperties().Where(p => p.GetGetMethod().IsVirtual && !p.GetGetMethod().IsFinal)) { expression.ForSourceMember(property.Name, opt => opt.Ignore()); } return expression; } }
当我们使用一些虚拟属性时,我不得不重写扩展,如下所示:
private static readonly Type CollectionBaseType = typeof(ICollection<>); public static IMappingExpression IgnoreNavigationProperties( this IMappingExpression expression) { var desType = typeof(TDestination); foreach (var property in desType.GetProperties() .Where(p => IsCollectionProperty(p) || HasForeignKeyAttribute(p))) { expression.ForMember(property.Name, opt => opt.Ignore()); } return expression; } private static bool IsCollectionProperty(PropertyInfo property) { var propertyType = property.PropertyType; return propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == CollectionBaseType; } private static bool HasForeignKeyAttribute(PropertyInfo property) => property.GetCustomAttribute() != null;
本质上,我检查属性是ICollection<>
类型还是具有[ForeignKey]
属性。
要纠正@Alexei的答案,请不要使用ForSourceMember
方法,就像在github上的这个问题中的答案一样。 它只是用于validation。
另一种方法是在这个答案中使用ForAllPropertyMaps
。