0

我想将 3 个不同的类映射到一个 DTO 中,每个属性在源和目标上都有相同的名称,类如下:

  • 用户
  • 候选人
  • 文件夹

这是 DTO 以及我想如何映射我的对象:

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
    }

我一直在寻找,我找到了这个解决方案,但我没有得到方法ConstructUsing

那么我该怎么做才能进行多对一映射,如果没有任何解决方法,这可能吗?

4

2 回答 2

1

这很大程度上取决于您的对象之间的关系。如果您的对象之间有 1:1 的关系(例如,如果User有属性User.CandidateUser.Portfolio),那么映射很容易:-

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...

如果您没有一对一的映射,则需要自己安排一些事情:-

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...

CandidateTextInfoSource然后,您可以根据对象之间的关系使用所需的任何方法来创建您的对象。例如,如果我假设 aUser有一个集合User.Candidates,并且 aCandidate有一个属性Candidate.Portfolio:-

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

我很欣赏这个答案很晚,但是如果您进一步指定对象之间的关系,我可以帮助您创建更具体的映射。

于 2015-05-05T10:52:24.433 回答
0

Automapper 的 ConstructUsing 对于从自定义代码构建一个属性很有用。在您的情况下,这并不是必需的。您只需要创建从对象到 DTO 的映射。然后将每个对象实例映射到同一个 DTO 实例。

但是,由于 Automapper 希望定义目标对象的每个属性以确保完全指定目标,因此您需要将每个映射配置为忽略源对象中不存在的属性

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

如果这是太多样板代码,则在堆栈溢出方面探索了许多解决方案,其中一个看起来很有希望:AutoMapper:“忽略其余的”?(看看罗伯特施罗德的回答)

于 2014-04-12T21:55:26.733 回答