Automapper 6.0.2.0,映射子实体时Mapper.Map()抛出StackOverflow [英] Automapper 6.0.2.0, Mapper.Map() throws StackOverflow when mapping Child Entities

查看:109
本文介绍了Automapper 6.0.2.0,映射子实体时Mapper.Map()抛出StackOverflow的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

直截了当,我得到了以下模型:

Getting straight to the point, I've got the following Models:

public abstract class ControlData
{
    public DateTime CreatedDate { get; set; }
    public int CreatedById { get; set; }
    [ForeignKey("CreatedById")]
    public Collaborator CreatedBy { get; set; }
    public DateTime? UpdatedDate { get; set; }
    public int? UpdatedById { get; set; }
    [ForeignKey("UpdatedById")]
    public Collaborator UpdatedBy { get; set; }
}

[Table("My_Position_Table")]
public class Position : ControlData
{
    [Key]
    [Column("PositionId")]
    public int Id { get; set; }
    [Column("PositionStatusId")]
    public int StatusId { get; set; }
    [ForeignKey("StatusId")]
    public PositionStatus Status { get; set; }
    public int OpportunityId { get; set; }


    [ForeignKey("OpportunityId")]
    public Opportunity Opportunity { get; set; }
    public int Total { get; set; }
    [Column("PositionDurationId")]
    public int DurationId { get; set; }
    [ForeignKey("DurationId")]
    public PositionDuration Duration { get; set; }
    public DateTime StartDate { get; set; }
    //TODO Agregar las otras propiedades con sus respectivos catalogos
    public string PracticeId { get; set; }
    [ForeignKey("PracticeId")]
    public Practice Practice { get; set; }
    public int RoleId { get; set; }
    [ForeignKey("RoleId")]
    public PersonRole Role { get; set; }
    public int PlatformId { get; set; }
    [ForeignKey("PlatformId")]
    public Platform Platform { get; set; }
    public int LevelId { get; set; }
    [ForeignKey("LevelId")]
    public Level Level { get; set; }
    public int EnglishLevelId { get; set; }
    [ForeignKey("EnglishLevelId")]
    public EnglishLevel EnglishLevel { get; set; }
    public string CountryId { get; set; }
    public int LocationId { get; set; }
    [ForeignKey("LocationId")]
    public Location Location { get; set; }
    public int? OfficeId { get; set; }
    public int OperationId { get; set; }
    [ForeignKey("OperationId")]
    public Person Operation { get; set; }
    public int? EvaluatorId { get; set; }
    [ForeignKey("EvaluatorId")]
    public Collaborator Evaluator { get; set; }
    public int? SourcerId { get; set; }
    [ForeignKey("SourcerId")]
    public Collaborator Sourcer { get; set; }
    public List<Candidate> Candidates { get; set; }
    public int? PositionCancellationReasonId { get; set; }
    [ForeignKey("PositionCancellationReasonId")]
    public PositionCancellationReason CancellationReason { get; set; }
    public string CancellationComments { get; set; }
    public int? CancellationById { get; set; }
    [ForeignKey("CancellationById")]
    public Collaborator CancellationBy { get; set; }
    public DateTime? CancellationDate { get; set; }
    public bool Active { get; set; }
    public bool WhereAvailable { get; set; }
    public bool RequestAsset { get; set; }
    public string CityZone { get; set; }
    public string TravelsTo { get; set; }
    public string Description { get; set; }
    public string SpecificationFile { get; set; }
    public int PositionPriorityId { get; set; }
    public int? SourcingGroupId { get; set; }
}

[Table("My_Opportunity_Table")]
public class Opportunity : ControlData
{
    [Column("OpportunityId")]
    [Key]
    public int Id { get; set; }
    [Column("OpportunityStatusId")]
    public int StatusId { get; set; }
    [ForeignKey("StatusId")]
    public OpportunityStatus Status { get; set; }
    public string ProjectId { get; set; }
    [ForeignKey("ProjectId")]
    public Project Project { get; set; }
    public string MarketId { get; set; }
    [ForeignKey("MarketId")]
    public Market Market { get; set; }
    public string CustomerId { get; set; }
    [ForeignKey("CustomerId")]
    public Customer Customer { get; set; }
    public string Name { get; set; }
    [Column("OpportunityTypeId")]
    public int TypeId { get; set; }
    [ForeignKey("TypeId")]
    public OpportunityType Type { get; set; }
    [Column("OpportunityPriorityId")]
    public int PriorityId { get; set; }
    [ForeignKey("PriorityId")]
    public OpportunityPriority Priority { get; set; }
    public int? OpportunityCancellationReasonId { get; set; }
    [ForeignKey("OpportunityCancellationReasonId")]
    public OpportunityCancellationReason CancellationReason { get; set; }
    public string CancellationComments { get; set; }
    public int? CancellationById { get; set; }
    [ForeignKey("CancellationById")]
    public Collaborator CancellationBy { get; set; }
    public DateTime? CancellationDate { get; set; }
    public bool Active { get; set; }        
    public List<OpportunityRole> OpportunityRoles { get; set; }
    public List<Position> Positions { get; set; }

}

而且,我在DTO中也有类似的东西:

And also, I've got their equivalents in DTO's:

public abstract class ControlDataDTO
{

    public DateTime CreatedDate { get; set; }
    public int CreatedById { get; set; }
    public CollaboratorPlainDTO CreatedBy { get; set; }
    public DateTime? UpdatedDate { get; set; }
    public int? UpdatedById { get; set; }
    public CollaboratorPlainDTO UpdatedBy { get; set; }
}

public class PositionDTO: ControlDataDTO
{

    public int Id { get; set; }
    public int StatusId { get; set; }
    public PositionStatusDTO Status { get; set; }
    public int OpportunityId { get; set; }
    public OpportunityDTO Opportunity { get; set; }
    public int Total { get; set; }
    public int DurationId { get; set; }
    public PositionDurationDTO Duration { get; set; }
    public DateTime StartDate { get; set; }
    public string PracticeId { get; set; }
    public PracticeDTO Practice { get; set; }
    public int RoleId { get; set; }
    public PersonRoleDTO Role { get; set; }
    public int PlatformId { get; set; }
    public PlatformDTO Platform { get; set; }
    public int LevelId { get; set; }
    public LevelDTO Level { get; set; }
    public int EnglishLevelId { get; set; }
    public EnglishLevelDTO EnglishLevel { get; set; }
    public string CountryId { get; set; }
    public int LocationId { get; set; }
    public LocationDTO Location { get; set; }
    public int? OfficeId { get; set; }
    public int OperationId { get; set; }
    public PersonDTO Operation { get; set; }
    public string OperationIS { get; set; }
    public bool WhereAvailable { get; set; }
    public bool RequestAsset { get; set; }
    public string CityZone { get; set; }
    public string TravelsTo { get; set; }
    public string Description { get; set; }
    public int CandidatesAccepted { get; set; }
    public int CandidatesRejected { get; set; }
    public int CandidatesWaiting { get; set; }
    public bool HasCandidatesWaiting { get; set; }
    public int TotalCandidates { get; set; }
    public string SpecificationFile { get; set; }
    public int? EvaluatorId { get; set; }
    public int? SourcerId { get; set; }
    public CollaboratorDTO Sourcer { get; set; }
    public int? SourcingGroupId { get; set; }
    public PositionCancellationReasonDTO CancellationReason { get; set; }
}

public class OpportunityDTO: ControlDataDTO
{

    public int Id { get; set; }
    public int StatusId { get; set; }
    public OpportunityStatusDTO Status { get; set; }
    public string ProjectId { get; set; }
    public ProjectDTO Project { get; set; }
    public string MarketId { get; set; }
    public MarketDTO Market { get; set; }
    public string CustomerId { get; set; }
    public CustomerDTO Customer { get; set; }
    public string Name { get; set; }
    public int TypeId { get; set; }
    public OpportunityTypeDTO Type { get; set; }
    public int PriorityId { get; set; }
    public OpportunityPriorityDTO Priority { get; set; }
    public int? OpportunityCancellationReasonId { get; set; }
    public OpportunityCancellationReasonDTO CancellationReason { get; set; }
    public string CancellationComments { get; set; }
    public int? CancellationById { get; set; }
    public CollaboratorPlainDTO CancellationBy { get; set; }
    public DateTime? CancellationDate { get; set; }
    public CollaboratorDTO Responsible { get; set; }
    public List<OpportunityRoleDTO> OpportunityRoles { get; set; }
    public int TotalPositions { get; set; }
    public bool CandidatesWarning { get; set; }
    public bool Active { get; set; }
    public List<PositionDTO> Positions { get; set; }
}

对于这种映射初始化,我们使用个人档案",如下所示:

For this mapping initialization we are using Profiles, like this way:

public class AutoMapperConfig
{
    public static void RegisterMappings()
    {
        Mapper.Initialize(cfg =>
        {
            // ...
            cfg.AddProfile<OpportunityMappingProfile>();
            // ...
        });
    }
}

public class OpportunityMappingProfile : Profile
{
    public OpportunityMappingProfile()
    {
        CreateMap<Opportunity, OpportunityDTO>()
            .ForMember(x => x.Responsible, x => x.MapFrom(c => GetFromOpportunityRoles(c.OpportunityRoles, Constants.OpportunityResponsible)))
            .ForMember(x => x.TotalPositions, x => x.MapFrom(c => c.Positions.Count()))
            .ForMember(x => x.CandidatesWarning, x => x.MapFrom(c => c.Positions.Count() > 0 ? 
                c.Positions.Any(pos => pos.Candidates.Any(cand => cand.StatusId == 3)) : 
                false))
            .ForMember(x => x.CreatedBy, x => x.MapFrom(c => Mapper.Map<CollaboratorPlainDTO>(c.CreatedBy)))
            .ForMember(x => x.UpdatedBy, x => x.MapFrom(c => Mapper.Map<CollaboratorPlainDTO>(c.UpdatedBy)))
            .ForMember(x => x.Positions, x => x.MapFrom(c => Mapper.Map<List<PositionDTO>>(c.Positions))).PreserveReferences(); --> Even using this method, StackOverflow exception is still occurring...
        CreateMap<OpportunityDTO, Opportunity>()
            .ForMember(x => x.CancellationReason, x => x.Ignore())
            .ForMember(x => x.CreatedBy, x => x.Ignore())
            .ForMember(x => x.UpdatedBy, x => x.Ignore())
            .ForMember(x => x.Positions, x => x.Ignore());
    }

    private Collaborator GetFromOpportunityRoles(List<OpportunityRole> opportunityRoles, string rol)
    {
        var opportunityRole = opportunityRoles.FirstOrDefault(opp => opp.ProjectRoleTypeId == rol);
        return opportunityRoles != null ? opportunityRole.Collaborator : null;
    }
}

最后,在我得到注释错误的地方进行映射的逻辑...

And finally, the logic that does the mapping where I'm getting the commented error...

public class OpportunityLogic : IOpportunityLogic
{
    // Properties...

    public OpportunityLogic(parameters list here, though irrelevant for this example)
    {
        // ...
    }

    public ActionResponse<List<OpportunityDTO>> GetOpportunitiesWithPositions(int personId)
    {
        // Information is retrieved from DB, here...
        List<Opportunity> listOpportunities = opportunityRepository.Get(                
            opp => opp.Status,
            opp => opp.Market,
            opp => opp.Customer,
            opp => opp.Type,
            opp => opp.Project,
            opp => opp.Status,
            opp => opp.Positions,
            opp => opp.Positions.Select(pos => pos.Candidates),
            opp => opp.Positions.Select(pos => pos.Status),
            opp => opp.Positions.Select(pos => pos.Practice),
            opp => opp.Positions.Select(pos => pos.Role),
            opp => opp.Positions.Select(pos => pos.Platform),
            opp => opp.Positions.Select(pos => pos.Sourcer));

        // After having retrieved data, here I re-define my model.
        listOpportunities = listOpportunities
            .Where( opp => opp.StatusId == (int)Constants.OpportunityStatus.Open &&
                           opp.Active == true &&
                           opp.Positions.Any(pos => pos.StatusId == (int)Constants.PositionStatus.Open &&
                                                    pos.Candidates.Any(can => can.PersonId == personId &&
                                                                              can.Active == true &&
                                                                              (can.StatusId == (int)Constants.CandidateStatus.Lead || 
                                                                               can.StatusId == (int)Constants.CandidateStatus.Waiting))))
            .ToList();

        // MY PROBLEM IS HERE....
        var mappedOpportunities = Mapper.Map<List<OpportunityDTO>>(listOpportunities);            

        return new ActionResponse<List<OpportunityDTO>> (mappedOpportunities);

    }
}

尝试将我的模型( List )映射到DTO( List )时,我的问题开始了;该错误是众所周知的" StackOverflow异常".如果我使用的是" PreserveReferences()"方法,为什么仍会引发相同的异常?在尝试了不同的深度级别(1,2,3 ...)之后," MaxDepth()方法"也是如此.

My problem starts when trying to map my Model (List) to the DTO (List); the error is the well-known "StackOverflow Exception". If I'm using the "PreserveReferences()" method, why is still throwing the same exception?. The same goes for "MaxDepth() method", after having tried different depth levels (1,2,3...).

我花了很多时间试图解决这个问题,老实说,我已经没有想法了.如果有人知道在这里做什么,我将不胜感激. 谢谢和前进&问候!

I've spent too many hours trying to solve this issue and to be honest, I'm out of ideas already. If anyone has an idea what to do here, I'll be really grateful. Thanks and advance & regards!!

推荐答案

这里的问题是我缺少需要保留其引用的 另一个映射配置文件 ,但是在这里没有提到,因为我错过了那一部分,而那正是导致我所有问题的那一部分.

The issue here is that I was missing another Mapping Profile that needed to preserve its references, but had not mentioned here, since I was missing that part and that was the one that had causing me all the issues.

这篇关于Automapper 6.0.2.0,映射子实体时Mapper.Map()抛出StackOverflow的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆