使用映射库将嵌套对象映射到C#中的自定义对象

时间:2018-05-21 21:04:26

标签: c# .net mapping automapper

我有以下对象结构:

/// <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; }
}

是否有任何可以轻松完成工作的映射器?

2 个答案:

答案 0 :(得分:3)

您可以使用AutoMapper。要首先映射某些类型,您需要创建一些映射:

Mapper.Initialize(cfg => cfg
    .CreateMap<Message, MessageViewModel>());

这会创建从MessageMessageViewModel的映射。默认情况下,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可以映射以下内容,前提是已为其数据类型定义了配置:

  • 的IEnumerable
  • ICollection的
  • 的IList
  • 列表
  • 阵列

由于在您的案例中已经为列表的数据类型提供了映射,因此不需要进一步配置。

如果您想要映射具有不同名称的字段,或者您希望在此过程中进行一些基本级别验证,则可以使用以下语法来定义配置:

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