自动映射相同类型的子映射

时间:2017-02-19 15:24:58

标签: asp.net-mvc entity-framework mapping automapper

我首先使用具有相同类型的子父

的代码
public class Comment
{
    public int Id { get; set; }

    public string Text { get; set; }

    public int? ParentId { get; set; }

    public virtual Comment Parent { get; set; }
    public virtual IList<Comment> Child { get; set; }
}

Fluent API:

modelBuilder.Entity<Comment>().Property(c => c.ParentId).IsOptional();
modelBuilder.Entity<Comment>().HasMany(c => c.Child).WithOptional(c => c.Parent).HasForeignKey(c => c.ParentId);

在实体框架中这很好。但是当我尝试在Automapper上使用它时,我抛出了一个StackOverflowException。

AutoMapperConfig:

cfg.CreateMap<Comment, CommentDTO>().ForMember(d => d.Child, opt => opt.UseDestinationValue());

CommentDTO:

public class CommentDTO
{
    public int Id { get; set; }

    public string Text { get; set; }

    public int? ParentId { get; set; }

    public virtual CommentDTO Parent { get; set; }
    public virtual IList<CommentDTO> Child { get; set; }
}

控制器:

Context.Comments.GetAll().AsNoTracking().ProjectTo<CommentDTO>().AsQueryable();

1 个答案:

答案 0 :(得分:1)

由于CommentCommentDTO中的媒体资源名称相同,您只需要指示AutoMapper映射它们,它就会为您完成:

Mapper.Initialize(x =>
        x.CreateMap<Comment, CommentDTO>().ReverseMap()
            .PreserveReferences()); 

我使用ReverseMap来允许双向映射。然后你可以随时使用它;

var commentDto = new CommentDTO { Child = new List<CommentDTO>(), Id = 1 };
var mapped = Mapper.Map<Comment>(commentDto);
var reverse = Mapper.Map<CommentDTO>(mapped);

最后一点,在.NET命名约定中,如果缩写包含2个字符,例如Input Output > IO,则建议对System.IO这两个字符使用大写。但如果它超过2,如Data Transfer Object > DTO,则建议使用Pascal表示法。因此,您的班级名称应为CommentDto而不是CommentDTO