我有以下对象结构:
/// <summary>
/// nested message instance provided by a business service
/// </summary>
public class Message
{
public string Subject { get; set; }
public DateTime CreationDate { get; set; }
public List<Message> Messages { get; set; }
}
我希望将该对象映射到以下对象结构:
/// <summary>
/// UI Object used to display a nested message structure
/// </summary>
public class MessageViewModel : ViewModelBase
{
public bool IsSelected { get; set; }
public string Subject { get; set; }
public DateTime CreationDate { get; set; }
public List<MessageViewModel> Messages { get; set; }
}
是否有任何可以轻松完成工作的映射器?
答案 0 :(得分:3)
您可以使用AutoMapper。要首先映射某些类型,您需要创建一些映射:
Mapper.Initialize(cfg => cfg
.CreateMap<Message, MessageViewModel>());
这会创建从Message
到MessageViewModel
的映射。默认情况下,AutoMapper会映射具有相同名称的所有属性。当指定了类型的映射时,也会映射嵌套的复杂属性。因此,在您的示例中,上面的映射就足够了,因为嵌套属性类型与其父类型相同,并且源类型的每个属性在目标类型中都具有相同的属性。集合隐式映射到其他集合。
要映射具体对象,您可以使用Mapper.Map
方法:
var messageViewModel = Mapper.Map<MessageViewModel>(message);
这只是静态映射器的示例,但也可以将mapper创建为对象。有关更高级的主题,您可以阅读文档:http://docs.automapper.org/en/stable/
答案 1 :(得分:3)
我强烈建议使用Automapper,因为它非常简单易用。在Automapper中,默认情况下会映射具有相同名称的字段,并且需要最少的配置。您想要实现的映射将按如下方式完成:
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Message, MessageViewModel>();
});
如果是集合,Automapper可以映射以下内容,前提是已为其数据类型定义了配置:
由于在您的案例中已经为列表的数据类型提供了映射,因此不需要进一步配置。
如果您想要映射具有不同名称的字段,或者您希望在此过程中进行一些基本级别验证,则可以使用以下语法来定义配置:
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Message, MessageViewModel>()
.ForMember(destination => destination.SomeDestinationField, map => map.MapFrom(source => source.SomeSourceFieldWithDifferentName))
.ForMember(destination => destination.SomeDestinationField, map => map.MapFrom(source => source.SomeSourceField ?? SomeDefaultValue));
});
然后我们可以使用MapperConfiguration对象来初始化Mapper并执行我们的映射,如下所示:
SourceClass SourceObject = new SourceClass();
// Populate SourceObject with values
var mapper = config.CreateMapper();
DesitnationClass DestinationObject = mapper.Map<DesitnationClass>(SourceObject);
我建议您浏览这些docs。