【问题标题】:Mapping a DTO to an EF entity Exception将 DTO 映射到 EF 实体异常
【发布时间】:2017-12-15 18:45:32
【问题描述】:

我有一份申请工作的申请。一旦申请人填写了所有信息并提交了申请,我想保存它。目前,我有一个组件来保存与数据模型(个人信息、可用性等)相关的应用程序的每个部分。当我运行它时,我得到一个异常状态:

找到未映射的成员。查看下面的类型和成员。 添加自定义映射表达式、忽略、添加自定义解析器或修改源/目标类型

对于没有匹配的构造函数,添加一个无参数 ctor,添加可选参数,或映射所有构造函数参数

CandidateDto -> 候选(目标成员列表) EmploymentApplication.Common.DataTransferObjects.CandidateDto -> EmploymentApplication.Entities.Candidate(目标成员列表)

未映射的属性: 地址 ID 候选人申请 候选人可用性 候选人教育 候选人就业历史 候选人参考 候选电信许可证

我尝试在 MapFrom 语句中指定 AddressId,其余的只是 EF 导航属性,在映射初始化中我说过要忽略。不幸的是,错误仍然存​​在,我现在不知道该怎么办。

这是我的映射:

        Mapper.Initialize(m => m.CreateMap<Candidate, CandidateDto>());
        Mapper.Initialize(m => m.CreateMap<CandidateDto, Candidate>()
            .ForMember(dest => dest.AddressId, opt => opt.MapFrom(src => src.Address.AddressId))
            .ForMember(dest => dest.CandidateApplications, opt => opt.Ignore())
            .ForMember(dest => dest.CandidateAvailabilities, opt => opt.Ignore())
            .ForMember(dest => dest.CandidateEducations, opt => opt.Ignore())
            .ForMember(dest => dest.CandidateEmploymentHistories, opt => opt.Ignore())
            .ForMember(dest => dest.CandidateReferences, opt => opt.Ignore())
            .ForMember(dest => dest.CandidateTeleLicenses, opt => opt.Ignore())
        );

这里是实际发生 Mapping 的组件方法:

        public void SaveCandidateInfo(CandidateDto candidateDto)
    {
        var candidateInfoToAdd = _mapper.Map<Candidate>(candidateDto);
        _candidateRepository.Add(candidateInfoToAdd);
        _candidateRepository.Save();
    }

这是 DTO:

    public class CandidateDto
{
    public Guid CandidateId { get; set; }
    public AddressDto Address { get; set; }
    public UserAccountDto UserAccount { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string PrimaryPhone { get; set; }
    public string Email { get; set; }
    public bool HasWorkEligibility { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateModified { get; set; }
    public Guid CreatedBy { get; set; }
    public Guid ModifiedBy { get; set; }
    public Guid UserAccountId { get; set; }
}

最后,这里是一个候选人的 EF 类:

 public partial class Candidate
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Candidate()
    {
        this.CandidateApplications = new HashSet<CandidateApplication>();
        this.CandidateAvailabilities = new HashSet<CandidateAvailability>();
        this.CandidateEducations = new HashSet<CandidateEducation>();
        this.CandidateEmploymentHistories = new HashSet<CandidateEmploymentHistory>();
        this.CandidateReferences = new HashSet<CandidateReference>();
        this.CandidateTeleLicenses = new HashSet<CandidateTeleLicense>();
    }

    public System.Guid CandidateId { get; set; }
    public Nullable<System.Guid> AddressId { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public System.DateTime DateOfBirth { get; set; }
    public string PrimaryPhone { get; set; }
    public string Email { get; set; }
    public bool HasWorkEligibility { get; set; }
    public System.DateTime DateCreated { get; set; }
    public System.DateTime DateModified { get; set; }
    public System.Guid CreatedBy { get; set; }
    public System.Guid ModifiedBy { get; set; }
    public System.Guid UserAccountId { get; set; }

    public virtual Address Address { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<CandidateApplication> CandidateApplications { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<CandidateAvailability> CandidateAvailabilities { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<CandidateEducation> CandidateEducations { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<CandidateEmploymentHistory> CandidateEmploymentHistories { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<CandidateReference> CandidateReferences { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<CandidateTeleLicense> CandidateTeleLicenses { get; set; }
    public virtual UserAccount UserAccount { get; set; }
}

感谢您的帮助!

【问题讨论】:

  • 您的配置向后看。你有CreateMap&lt;CandidateDto, Candidate&gt;(),但你有.ForMember(dest =&gt; dest.AddressId, opt =&gt; opt.MapFrom(src =&gt; src.Address.AddressId))。其中说CanditateDto 有一个Address 属性。而且你只需要一个 Initialize。
  • CandidateD 没有地址属性吗?
  • 您使用的是哪个 AM 版本?您还可以提供完整的复制(a.k.a.minimal reproducible example
  • AutoMapper 版本 6.2.2。我现在将添加存储库。
  • 从来没有弄明白,所以我决定手动将它们映射到保存数据的方法中。不是我所知道的最漂亮的方法,但我不知道还能做什么。

标签: c# entity-framework automapper dto


【解决方案1】:

您定义了一些关于目标属性的配置以忽略它们,但是当您尝试映射它时,没有应该传递Map 方法的目标实例。所以,忽略属性是没有关系的。

所以,你应该改变它;

var candidateInfoToAdd = _mapper.Map<Candidate>(candidateDto);

var candidateInfoToAdd = new Candidate();
_mapper.Map<CandidateDto,Candidate>(candidateDto, candidateInfoToAdd);

【讨论】:

  • 嗯,我试过了,但在运行时得到了相同的原始异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-14
  • 1970-01-01
  • 1970-01-01
  • 2018-09-13
  • 2021-12-31
相关资源
最近更新 更多