M05Pr1mty
M05Pr1mty

Reputation: 731

Automapper Issue: Recursive Projection LinqToSql Stackoverflow Exception

enter image description here

Using the above LinqToSql entity classes and trying to map to like-named DTO objects throws a Stackoverflow Exception. I've read around and this appears to be a problem with the Child/Parent relationship with the CriteriaGroup object. Does anyone have any suggestions?

Code used to call this:

var mappedDtos = this.configurationRepository
                        .GetAll()
                        .Project()
                        .To<CriteriaGroupDto>();

Where GetAll() is:

public override IQueryable<TEntity> GetAll()
{
    return this.Table.AsQueryable();
}    

The mapping code I've made for this is:

/// <summary>
/// The criteria profile.
/// </summary>
public class CriteriaProfile : Profile
{
    /// <summary>
    /// The configure.
    /// </summary>
    protected override void Configure()
    {
        Mapper.CreateMap<CriteriaGroup, CriteriaGroupDto>()
                .ForMember(dest => dest.Groups, opt => opt.MapFrom(src => src.Children))
                .ForMember(dest => dest.Parent, opt => opt.MapFrom(src => src.Parent))
                .ForMember(dest => dest.Criteria, opt => opt.MapFrom(src => src.CriteriaConfigs));

        Mapper.CreateMap<CriteriaConfig, CriteriaConfigDto>()
            .Include<RatingConfig, CriteriaConfigDto>()
            .Include<CountryConfig, CriteriaConfigDto>()
            .Include<TimescaleConfig, CriteriaConfigDto>()
            .ForMember(dest => dest.DefaultValue, opt => opt.UseValue(default(object)))
            .ForMember(dest => dest.DataType, opt => opt.Ignore())
            .ForMember(dest => dest.ElementId, opt => opt.MapFrom(src => src.Id))
            .ForMember(dest => dest.Options, opt => opt.Ignore());

        Mapper.CreateMap<RatingConfig, CriteriaConfigDto>()
            .ForMember(dest => dest.JoinOperators, opt => opt.MapFrom(src => src.JoinOperators))
            .ForMember(dest => dest.OptionOperators, opt => opt.MapFrom(src => src.Operators));

        Mapper.CreateMap<CountryConfig, CriteriaConfigDto>()
            .ForMember(dest => dest.JoinOperators, opt => opt.MapFrom(src => src.JoinOperators))
            .ForMember(dest => dest.OptionOperators, opt => opt.MapFrom(src => src.Operators));

        Mapper.CreateMap<TimescaleConfig, CriteriaConfigDto>()
            .ForMember(dest => dest.JoinOperators, opt => opt.MapFrom(src => src.JoinOperators))
            .ForMember(dest => dest.OptionOperators, opt => opt.MapFrom(src => src.Operators));

        base.Configure();
    }
}

Whereby the additional mappings in the derrived classes are due to: (EG)

/// <summary>
/// The rating config.
/// </summary>
public partial class RatingConfig
{
    /// <summary>
    /// Gets the operators.
    /// </summary>
    public IEnumerable<RatingOperator> Operators
    {
        get
        {
            return Enumeration.GetAll<RatingOperator>();
        }
    }

    /// <summary>
    /// Gets the join operators.
    /// </summary>
    public IEnumerable<RuleJoinOperator> JoinOperators
    {
        get
        {
            return Enumeration.GetAll<RuleJoinOperator>();
        }
    }
}

Upvotes: 8

Views: 983

Answers (0)

Related Questions