我有一个简单的更新功能:
public void Update(Users user)
{
tblUserData userData = _context.tblUserDatas.Where(u => u.IDUSER == user.IDUSER).FirstOrDefault();
if (userData != null)
{
Mapper.CreateMap<Users, tblUserData>();
userData = Mapper.Map<Users, tblUserData>(user);
_context.SaveChanges()
}
}
userData是一个EF实体,它的Entity Key属性被删除,因为我相信它存在于目标对象中,但不存在于源对象中,因此它将使用其默认值进行映射(对于实体键) ,那是空的)
所以,我的问题是,Automapper是否可以配置为仅尝试映射源对象和目标对象中存在的属性?我想要跳过实体键和导航属性等内容。
答案 0 :(得分:10)
如果需要,您可以明确告诉AutoMapper
Ignore
某些属性:
Mapper.CreateMap<Users, tblUserData>()
.ForMember(dest => dest.Id, opt => opt.Ignore());
这意味着目标对象中的Id列始终保持不变。
您可以使用Condition
选项指定是否应用映射,具体取决于逻辑条件的结果,如下所示:
Mapper.CreateMap<Users, tblUserData>()
.ForMember(dest => dest.Id, opt => opt.Condition(src=>src.Id.HasValue));
或
Mapper.CreateMap<Users, tblUserData>()
.ForMember(dest => dest.Id, opt => opt.Condition(src=>src.Id != null));
取决于您的具体要求。
答案 1 :(得分:5)
您可以告诉AutoMapper忽略您不希望映射的字段,如下所示:
userData = Mapper.Map<Users, tblUserData>(user).ForMember(m => m.EntityKey, opt => opt.Ignore());
答案 2 :(得分:4)
您可以通过使用小扩展方法来忽略目标类型上不存在的所有属性来覆盖此行为。
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();
也可以根据需要自定义此方法,具体来说,例如,忽略具有受保护或私有设置器的属性。
答案 3 :(得分:1)
代替
userData = _mapper.Map<Users, tblUserData>(user);
使用
_mapper.Map(user, userData);
前者创建一个仅具有用户对象中可用属性的新userData对象。稍后将用用户对象中存在的属性覆盖现有的userData对象的属性,同时保留其余部分。