使用AutoMapper,是否可以仅将已更改的属性从视图模型映射到域对象?
我遇到的问题是,如果视图模型上有未更改的属性(null),那么它们将覆盖域对象并持久保存到数据库。
答案 0 :(得分:14)
是的,可以这样做,但您必须在映射配置中使用Condition()
指定何时跳过目标属性。
这是一个例子。请考虑以下类:
public class Source
{
public string Text { get; set; }
public bool Map { get; set; }
}
public class Destination
{
public string Text { get; set; }
}
第一张地图不会覆盖destination.Text
,但第二张地图会覆盖。
Mapper.CreateMap<Source, Destination>()
.ForMember(dest => dest.Text, opt => opt.Condition(src => src.Map));
var source = new Source { Text = "Do not map", Map = false };
var destination = new Destination { Text = "Leave me alone" };
Mapper.Map(source, destination);
source.Map = true;
var destination2 = new Destination { Text = "I'll be overwritten" };
Mapper.Map(source, destination2);
答案 1 :(得分:3)
是;我编写了这个扩展方法,只将脏的值从模型映射到Entity Framework。
public static IMappingExpression<TSource, TDestination> MapOnlyIfDirty<TSource, TDestination>(
this IMappingExpression<TSource, TDestination> map)
{
map.ForAllMembers(source =>
{
source.Condition(resolutionContext =>
{
if (resolutionContext.SourceValue == null)
return !(resolutionContext.DestinationValue == null);
return !resolutionContext.SourceValue.Equals(resolutionContext.DestinationValue);
});
});
return map;
}
示例:
Mapper.CreateMap<Model, Domain>().MapOnlyIfDirty();
答案 2 :(得分:1)
@Matthew Steven Monkan是正确的,但似乎AutoMapper改变了API。我会把新的一个推给别人参考。
public static IMappingExpression<TSource, TDestination> MapOnlyIfChanged<TSource, TDestination>(this IMappingExpression<TSource, TDestination> map)
{
map.ForAllMembers(source =>
{
source.Condition((sourceObject, destObject, sourceProperty, destProperty) =>
{
if (sourceProperty == null)
return !(destProperty == null);
return !sourceProperty.Equals(destProperty);
});
});
return map;
}
这就是全部
答案 3 :(得分:0)
没有
这正是您从未从viewmodel映射到域模型的原因之一。域/业务模型更改对于要处理的工具来说太重要了。
手动:
customer.LastName = viewModel.LastName
改变业务状态太重要了。