jeudi 10 avril 2014

c# - Automapper question : Recursive Projection LinqToSql Stackoverflow Exception - débordement de pile


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>();
}
}
}


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>();
}
}
}

0 commentaires:

Enregistrer un commentaire