代码之家  ›  专栏  ›  技术社区  ›  Ogglas

自引用循环导致映射堆栈溢出

  •  1
  • Ogglas  · 技术社区  · 7 年前

    根据文档,应尽可能为AutoMapper自动设置参考。

    从6.1.0开始,preserverences在配置时自动设置

    https://github.com/AutoMapper/AutoMapper/wiki/5.0-Upgrade-Guide

    我还尝试将MaxDepth设置为1,但在以下映射中仍然出现堆栈溢出异常。我能以某种方式绕过这个问题吗?或者我需要修改视图模型吗?

    cfg.CreateMap<ArticleViewModel, Article>(MemberList.Source)
        .MaxDepth(1)
        .EqualityComparison((src, dst) => src.Id == dst.Id);
    

    导致堆栈溢出异常的代码:

    var article = await iArticleRepository.GetAsync(id);
    //The mapping below causes the exception
    var mappedArticle = Mapper.Map<ArticleViewModel>(article);
    

    实体:

    public class Article: IEntity<int>
    {
        [Key]
        public int Id { get; set; }
    
        ...
    
        public int SupplierId { get; set; }
    
        public virtual Supplier Supplier { get; set; }
    }
    
    public class Supplier: IEntity<int>
    {
        [Key]
        public int Id { get; set; }
    
        ...
    
        public virtual ICollection<Contact> Contacts { get; set; }
    }
    
    public class Contact: IEntity<int>
    {
        [Key]
        public int Id { get; set; }
    
        ...
        public virtual ICollection<Supplier> Suppliers { get; set; }
    }
    

    public class ArticleViewModel
    {
        public int Id { get; set; }
    
        ...
        public SupplierViewModel Supplier { get; set; }
    
    }
    
    public class SupplierViewModel
    {
        public int Id { get; set; }
    
        ...
        public List<ContactViewModel> Contacts { get; set; }
    
    }
    
    public class ContactViewModel
    {
        public int Id { get; set; }
        ... 
        public List<SupplierViewModel> Suppliers { get; set; }
    }
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   Ogglas    7 年前

    嗯,不清楚什么是 意思是因为之前的文件表明

    事实证明,这种跟踪非常昂贵,您需要选择使用PreserveReferences来实现圆形地图

    不可能

    不要依赖于此,而是使用显式选择加入。此示例模型中的循环参考介于 Supplier Contact ,因此您必须在其中一个涉及的类映射中指定,例如:

    cfg.CreateMap<ArticleViewModel, Article>(MemberList.Source)
        .MaxDepth(1)
        .EqualityComparison((src, dst) => src.Id == dst.Id);
    
    cfg.CreateMap<SupplierViewModel, Supplier>(MemberList.Source)
        .PreserveReferences()
        .EqualityComparison((src, dst) => src.Id == dst.Id);