36

I am having a hard time to understand how to map certain objects. Please answer some questions about this simple example.

Example code

class User
{
    private int id;
    private string name;
}

class Group
{
    private int id;
    private string name;
    private List<User> users;
}

[DataContract]
public class UserDto
{
    [DataMember]
    public int id { get; set; }
    [DataMember]
    public string name{ get; set; }      
}

[DataContract]
public class GroupDto
{
    [DataMember]
    public int id { get; set; }
    [DataMember]
    public string name{ get; set; }
    [DataMember]
    public List<User> Users { get; set; }      
}

The mappers

Mapper.CreateMap<User, UserDto>();
Mapper.CreateMap<UserDto, User>();

Mapper.CreateMap<Group, GroupDto>();
Mapper.CreateMap<GroupDto, Group>();

When mapping Group to GroupDto, do you have to map User to UserDto internally because the List<User> in Group consist of unmapped Users? If so how do you do this? My guess is

Mapper.CreateMap<Group, GroupDto>()
    .ForMember(g => g.id, opt => opt.Ignore());
    .ForMember(g => g.name, opt => opt.Ignore());
    .ForMember(g => g.Users, opt => opt.MapFrom(u => Mapper.Map<Group, UserDto>(u)))

Is this correct?

David
  • 965
  • 3
  • 12
  • 24
  • 4
    Why doesn't your GroupDTO contain UserDTO's? If it did, no more configuration other than `CreateMap` would be needed for AutoMapper to work. – stuartd Dec 17 '13 at 22:53
  • Here is simple article i have written on Automapper using C# http://www.codeproject.com/Articles/986460/What-is-Automapper – Shivprasad Koirala Jul 10 '15 at 18:55
  • Read this article: http://www.codearsenal.net/2012/12/csharp-object-to-object-mapping-automapper.html – ybonda Aug 30 '15 at 10:17
  • It would help if there was an updated copy of the article posted above. I don't believe it's valid in AutoMapper 5.x. – jocull Dec 22 '16 at 20:57

2 Answers2

31

1- Change the GroupDto to be like this:

[DataContract]
public class GroupDto
{
    [DataMember]
    public int id { get; set; }
    [DataMember]
    public string name{ get; set; }
    [DataMember]
    public List<UserDTO> Users { get; set; }      
}

2- Create your mappings :

Mapper.CreateMap<User, UserDto>();
Mapper.CreateMap<UserDto, User>(); // Only if you convert back from dto to entity

Mapper.CreateMap<Group, GroupDto>();
Mapper.CreateMap<GroupDto, Group>(); // Only if you convert back from dto to entity

3- that's all, because auto mapper will automatically map the List<User> to List<UserDto> (since they have same name, and there is already a mapping from user to UserDto)

4- When you want to map you call :

Mapper.Map<GroupDto>(groupEntity);

Hope that helps.

Omar.Alani
  • 4,050
  • 2
  • 20
  • 31
  • "since they have same name," -- does type important also? If one object is list and another one is ICollection, does it require a member mapping? – Emil Nov 30 '16 at 12:47
  • 2
    I would like to see an updated example for AutoMapper 5. I don't think most of this is valid anymore. – jocull Dec 22 '16 at 20:52
6

As @stuartd said, if you change :

[DataContract]
public class GroupDto
{
    [DataMember]
    public int id { get; set; }
    [DataMember]
    public string name{ get; set; }
    [DataMember]
    public List<User> Users { get; set; }      
}

for :

[DataContract]
public class GroupDto
{
    [DataMember]
    public int id { get; set; }
    [DataMember]
    public string name{ get; set; }
    [DataMember]
    public List<UserDTO> Users { get; set; }      
}

you just need :

Mapper.CreateMap()

Otherwise, change

Mapper.CreateMap<Group, GroupDto>()
    .ForMember(g => g.id, opt => opt.Ignore());
    .ForMember(g => g.name, opt => opt.Ignore());
    .ForMember(g => g.Users, opt => opt.MapFrom(u => Mapper.Map<Group, UserDto>(u)))

for something like :

Mapper.CreateMap<Group, GroupDto>()
    .ForMember(g => g.id, opt => opt.Ignore());
    .ForMember(g => g.name, opt => opt.Ignore());
    .ForMember(g => g.Users, opt => opt.MapFrom(u => Mapper.Map<List<User>>(g.Users)))

This has not been tested, but the idea is here....

Minus
  • 729
  • 8
  • 20