【问题标题】:Automapper Many to one map configurationAutomapper 多对一地图配置
【发布时间】:2014-05-27 00:15:01
【问题描述】:

我想将 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
    }

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

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

【问题讨论】:

  • 这些类有什么关系?他们互相引用吗?您可以根据命名约定使用 AutoMapper 的 flattening
  • 它们之间有共同的 id,但只有你建立“逻辑”关系,它们之间没有对象或嵌套引用

标签: c# mapping automapper automapper-3


【解决方案1】:

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: "Ignore the rest"?(查看 Robert Schroeder 的答案)

【讨论】:

    【解决方案2】:

    这很大程度上取决于您的对象之间的关系。如果您的对象之间存在 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。例如,如果我假设一个User 有一个集合User.Candidates,而一个Candidate 有一个属性Candidate.Portfolio:-

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多