简体   繁体   中英

Automapper Many to one map configuration

I want to map 3 different classes into a single DTO, each property have the same name on the source and the destination, the classes are the following:

  • User
  • Candidate
  • Portfolio

this is the DTO and how I want to map my objects:

public class CandidateTextInfo
    {
        public string ProfilePicture { get; set; }   //-->User
        public ObjectId UserId { get; set; }         //-->User
        public string Name { get; set; }             //--> Candidate
        public string Headline { get; set; }         //--> Candidate
        public Gender Gender { get; set; }           //--> Candidate
        public byte Rating { get; set; }             //--> Candidate
        public bool IsCompany { get; set; }          //--> Candidate
        public string[] Tags { get; set; }           //--> Portafolio
        public string[] Categories { get; set; }     //--> Portafolio
        public string ExecutiveSummary { get; set; } //--> Portafolio
        public HourlyRate HourlyRate{ get; set; }    //--> Candidate
    }

I've been looking in SO and I found this solution but I don't get the method ConstructUsing

so how can I do to have a many to one mapping, is that possible, if not any workaround?

It depends greatly on the relationships between your objects. If you have a 1:1 relationship between your objects (eg if User has properties User.Candidate and User.Portfolio ) then the mapping is easy:-

CreateMap<User, CandidateTextInfo>()
  .ForMember(d => d.ProfilePicture, o => o.MapFrom(s => s.ProfilePicture)
  // ...
  .ForMember(d => d.Name, o => o.MapFrom(s => s.Candidate.Name)
  // And so on...

If you don't have a one-to-one mapping, you need to arrange things a little bit yourself:-

public class CandidateTextInfoSource
{
  public CandidateTextInfoSource(User user,
                                 Candidate candidate,
                                 Portafolio portafolio)
  {
    this.User = user;
    this.Candidate = candidate;
    this.Portafolio = portafolio;
  }

  public User User { get; set; }
  public Candidate Candidate { get; set; }
  public Portafolio Portafolio { get; set; }
}

// ...

CreateMap<CandidateTextInfoSource, CandidateTextInfo>()
  .ForMember(d => d.ProfilePicture, o => o.MapFrom(s => s.User.ProfilePicture)
   // ...
  .ForMember(d => d.Name, o => o.MapFrom(s => s.Candidate.Name)
   // And so on...

You can then use whatever means you require to create your CandidateTextInfoSource depending on the relationship between your objects. For example, if I assume that a User has a collection User.Candidates , and a Candidate has a property Candidate.Portfolio :-

CreateMap<User, IEnuemerable<CandidateTextInfoSource>>()
  .ConstructUsing(
    x => x.Candidates
          .Select(y => Mapper.Map<CandidateTextInfo>(new CandidateTextInfoSource(x, y, y.Portfolio)))
  .ToList());

I appreciate that this answer is very late, but if you further specify the relationship between your objects, I can help you create a more specific mapping.

Automapper's ConstructUsing is useful to build one property from custom code. In your case it is not really necessary. You just need to create the maps from your objects to your DTO. Then map each object instance to the same DTO instance.

However since Automapper wants each property of the destination object to be defined in order to ensure that the destination is fully specified you will need to configure each mapping with the properties not existing in the source object as ignored

CreateMap<Candidate, CandidateTextInfo>()
.ForMember(x=> x.ProfilePicture, opt => opt.Ignore())
.ForMember(... 
// repeat for all destination properties not existing in source properties

If this is too much boilerplate code, many solutions are explored on stack overflow, among which this one looks promising: AutoMapper: "Ignore the rest"? (look at Robert Schroeder's answer)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM