2011-04-25 86 views
10

使用AutoMapper,是否可以仅将已更改的属性从视图模型映射到域对象?仅地图改变了属性?

我遇到的问题是,如果视图模型上的属性未更改(空),则它们将覆盖域对象并持久保存到数据库。

回答

13

是的,它可以完成,但您必须在映射配置中指定何时使用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); 
0

编号

这正是您从未将视图模型映射到域模型的原因之一。域/业务模型的变化对于工具来说太重要了。


手动:

customer.LastName = viewModel.LastName 

不断变化的业务状态是不这样做太重要了。

+4

什么?我认为这正是这是什么?请详细说明如何将您的域对象转换为您的视图模型。 – Sam 2011-04-25 18:43:15

+0

我在上面的意思是如何让你的编辑/视图模型回到你的域对象? – Sam 2011-04-25 18:52:10

+0

你是否在你的控制器中执行此操作? – Sam 2011-04-25 23:40:31

3

是;我编写了这个扩展方法来将脏模型中的脏值映射到实体框架。

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(); 
+1

SourceValue不是resolutioncontext的可用成员。我错过了什么? – CrusherJoe 2016-09-07 06:24:08

+0

是的,这些成员“SourceValue”和“DestinationValue”也不适用于我。 – JARRRRG 2017-03-24 09:15:12