Automapper循环参考无限循环

时间:2018-04-20 11:29:39

标签: c# .net api entity automapper

我对AutoMapper有一些问题,我映射的对象使用循环引用,因此我无法使用ActionResult将JSON返回给View。

我已将DTO的对象与另外两个对象联系起来。

 public class MasterJobsDTO
{
    public int function_id { get; set; }
    public string function_name { get; set; }
    public bool is_active { get; set; }
    public job_family job_family
    {
        get; set;

    }
    public functional_area functional_area
    {
        get; set;

    }
}

功能模式:

 public partial class function
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public function()
    {
        this.t_actual_organization = new HashSet<t_actual_organization>();
        this.t_actual_organization_split_position = new HashSet<t_actual_organization_split_position>();
    }

    public int function_id { get; set; }
    public string function_name { get; set; }
    public bool is_active { get; set; }
    public Nullable<int> job_family_id { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<t_actual_organization> t_actual_organization { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<t_actual_organization_split_position> t_actual_organization_split_position { get; set; }
    public virtual job_family job_family { get; set; }
}

Job_Family模型:

public partial class job_family
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public job_family()
    {
        this.t_actual_organization = new HashSet<t_actual_organization>();
        this.t_actual_organization_split_position = new HashSet<t_actual_organization_split_position>();
        this.functions = new HashSet<function>();
    }

    public int job_family_id { get; set; }
    public string job_family_name { get; set; }
    public Nullable<int> functional_area_id { get; set; }

    public virtual functional_area functional_area { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<t_actual_organization> t_actual_organization { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<t_actual_organization_split_position> t_actual_organization_split_position { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<function> functions { get; set; }
}

Automapper config:

cfg.CreateMap<function, MasterJobsDTO>().MaxDepth(1).PreserveReferences()
        .ForMember(x => x.functional_area_id, opts => opts.MapFrom(source => source.job_family.functional_area.functional_area_id))
        .ForMember(x => x.functional_area_extended_name, opts => opts.MapFrom(source => source.job_family.functional_area.functional_area_extended_name))
        .ForMember(x => x.job_family_name, opts => opts.MapFrom(source => source.job_family.job_family_name))
        .ForMember(x => x.functional_area, opts => opts.MapFrom(source => source.job_family.functional_area))
        ;

function_area class:

 public partial class functional_area
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public functional_area()
    {
        this.job_family = new HashSet<job_family>();
        this.t_actual_organization = new HashSet<t_actual_organization>();
        this.t_actual_organization_split_position = new HashSet<t_actual_organization_split_position>();
    }

    public int functional_area_id { get; set; }
    public string functional_area_name { get; set; }
    public string functional_area_extended_name { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<job_family> job_family { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<t_actual_organization> t_actual_organization { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<t_actual_organization_split_position> t_actual_organization_split_position { get; set; }
}

电话:

List<MasterJobsDTO> mjd = Mapper.Map<List<function>, List<MasterJobsDTO>>(data);

我在浏览器中遇到的错误是:

  

序列化“System.Data.Entity.DynamicProxies.job_family_D3FE2013BDB6002B7BE94915E73AEA531401 ...

类型的对象时检测到循环引用

谢谢!

2 个答案:

答案 0 :(得分:1)

在您的automapper配置中,您可以排除违规的循环参考点回。

.ForMember(dest => dest.OffendingVariable, source=> source.Ignore());

自动化程序完成后得到的结果将是&#34;更小&#34;而不是&#34;实体&#34;一,可以毫无问题地序列化为JSON。

编辑:如果你的真正错误在于你最终希望能够序列化你的&#34;无限&#34;反对JSON,你不关心通过摆弄自动播放器来修复它我可以提出&#34;裁剪&#34;用这样的东西沿着你的物体的圆形点后面:

List<MasterJobsDTO> mjd = Mapper.Map<List<function>, List<MasterJobsDTO>>(data);

var jsonPrepMJD = new List<MasterJobsDTO>(from m in mjd
                            select new MasterJobsDTO()
                            {
                              id = m.id,
                              ...,
                              pointBackMember = new PointBackMember(){set all but the virtual pointback}
                            }.Cast<MasterJobsDTO>();

如果pointBackMember是一个列表,那么从中选择并将其投射到您需要的深度

jsonPrepMJD将是可序列化的。

答案 1 :(得分:-1)

等等,automapper的问题还是json格式器无法处理循环引用(CR)?

如果是json,则可以配置api以处理CR。 Here是一个过度学术示例的链接,该示例说明了如何忽略CR。 Here是该设置的选项。我可以在WebApiConfig.cs中全局解决该问题

就我个人而言,我宁愿能够使json能够正确表示数据,而不愿意更改我的编码实践,因为我只能深入X级。

drawable-xxxx

我在新版本的automapper中遇到了类似的问题。 Automapper应该能够statically figure out the CRs in 6.1+,但是我有一个非常复杂的dto模型,带有许多CR。我正在等待自动映射器团队解决我的问题。在此期间,我恢复到4.2.1.0,一切正常。解决自动映射器异常后,我从json格式化程序收到了异常,并且上面的忽略配置解决了我的问题。

Here是引导我走上json问题的正确之路。