为什么.ForPath()导致StackOverflowException而.ForMember()没有?

时间:2018-09-25 16:44:42

标签: c# automapper stack-overflow automapper-7

我有实体类,用于使用EF和域类在数据库中存储对象。 EF类和域类都是自引用的。我在这里看到:AutoMapper throwing StackOverflowException when calling ProjectTo<T>() on IQueryable,不建议[让EF和域类进行自我引用],但是我看不到任何其他方式来调制对象。

当我使用AutoMapper配置.ForPath()时会导致StackOverflowException。使用.ForMember()有用。

我已经读过AutoMapper: What is the difference between ForMember() and ForPath()?,但答案基本上是:“他们是一样的”(不太有用)

最小演示:

using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;

class Program
{
    static void Main(string[] args)
    {
        var mapperConfig = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<Processor, ProcessorEntity>().ReverseMap();
            cfg.CreateMap<ScheduleEntity, Schedule>()
                .ForMember(dest => dest.Processor, opt => opt.MapFrom(src => src.Processor));
        });
        var mapperConfigStackOverflow = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<Processor, ProcessorEntity>().ReverseMap();
            cfg.CreateMap<ScheduleEntity, Schedule>()
                .ForPath(dest => dest.Processor, opt => opt.MapFrom(src => src.Processor));
        });

        var mapper = mapperConfig.CreateMapper();
        var stackOverflowMapper = mapperConfigStackOverflow.CreateMapper();

        var pe = new ProcessorEntity
        {
            Schedules = new List<ScheduleEntity>
            {
                new ScheduleEntity()
            }
        };
        pe.Schedules.First().Processor = pe;

        var processor = mapper.Map<Processor>(pe);
        Console.WriteLine("the processor:" + processor);

        Console.WriteLine("expect a stackoverflow in 3, 2, 1...");
        var neverSatisfied = stackOverflowMapper.Map<Processor>(pe);

    }
}

public class ProcessorEntity
{
    public ICollection<ScheduleEntity> Schedules { get; set; }
}

public class ScheduleEntity
{
    public ProcessorEntity Processor { get; set; }
}

public class Processor
{
    public ICollection<Schedule> Schedules { get; set; }
}

public class Schedule
{
    public Processor Processor { get; set; }
}

0 个答案:

没有答案