Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Recap about Creating Maps for AutoMapper in .NET Core

0.00/5 (No votes)
2 Oct 2018 1  
Different options to create the maps

Introduction

I have an ASP.NET Core MVC Web Applications with models and view models fitting the architecture of the database and fields required in each view. I choose Automapper to simplify the conversion between the object from the database and to the view. In some cases, the conversion is one to one, in others, one view models should be converted to many domain models.

Background

This link explains how to get started with Automapper in .NET Core. Also, here you can read about creating maps for different scenarios. Additionally, there are many comments on Stackoverflow about using tuples to create one to many classes maps.

Using the Code

First, you can create a map for a conversion from one domain model to one view model as follows:

CreateMap<ViewModels.Base, Models.Base>()
   .ForMember(dest => dest.BaseId, opts => opts.MapFrom(src => src.BaseId))
   .ForMember(dest => dest.UserId, opts => opts.MapFrom(src => src.UserId))
   .ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.Name));

CreateMap<ViewModels.Base, Models.Base>().ReverseMap();

If field names do not match, you need to specify them. You can define the reverse map.

On the other hand, for the case where a view model should be mapped with two domain models, you can use tuples as the following example.

CreateMap<System.Tuple<Models.Base, Models.BaseStatus>, ViewModels.Base>()
  .ForMember(dest => dest.BaseId, opts => opts.MapFrom(src => src.Item1.BaseId))
  .ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.Item1.Name))
  .ForMember(dest => dest.UserId, opts => opts.MapFrom(src => src.Item1.UserId))
  .ForMember(dest => dest.IsConnected, opts => opts.MapFrom(src => src.Item2.IsConnected))
  .ForMember(dest => dest.IsPlugged, opts => opts.MapFrom(src => src.Item2.IsPlugged));

For the reverse map, you will in each case pick the fields corresponding to each class:

CreateMap<ViewModels.Base, Models.Base>()
  .ForMember(dest => dest.BaseId, opts => opts.MapFrom(src => src.BaseId))
  .ForMember(dest => dest.UserId, opts => opts.MapFrom(src => src.UserId))
  .ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.Name));

CreateMap<ViewModels.Base, Models.BaseStatus>()
  .ForMember(dest => dest.BaseId, opts => opts.MapFrom(src => src.BaseId))
  .ForMember(dest => dest.IsConnected, opts => opts.MapFrom(src => src.IsConnected))
  .ForMember(dest => dest.IsPlugged, opts => opts.MapFrom(src => src.IsPlugged));

Another option, for the one to many mappings could be using class composition. As soon as Models.Base and ViewModels.Base contains a field that is the Models.BaseStatus.

CreateMap<Models.Base, ViewModels.Base>()
  .ForMember(dest => dest.BaseId, opts => opts.MapFrom(src => src.BaseId))
  .ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.Name))
  .ForMember(dest => dest.UserId, opts => opts.MapFrom(src => src.UserId))
  .ForMember(dest => dest.Status, opts => opts.MapFrom(src => new BaseStatus
            {
                  IsConnected = src.IsConnected,
                  IsPlugged = src.IsPlugged))
             };

Finally, this is the way the maps can be called:

ViewModels.Base vmb = _mapper.Map<BaseViewModel>(new Tuple<Models.Base, Models.BaseStatus>(b, bs));
ViewModels.Base vmb = _mapper.Map<Models.Base>(b);

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here