Sauron
Sauron

Reputation: 2356

Automapper map child of same type

I have code first that use child parent with same type

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

That's fine in entity framework. But when I try to use it on Automapper i throwing an 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; }
}

Controller:

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

Upvotes: 0

Views: 1034

Answers (1)

CodingYoshi
CodingYoshi

Reputation: 27039

Since your property names in both Comment and CommentDTO are the same, you just need to instruct AutoMapper to map them and it will do it for you:

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

I have used ReverseMap to allow mapping in both directions. Then you can use it whenever you want like this;

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

And one last note, in .NET naming convention, if an abbreviation contains 2 characters such as Input Output > IO then it is recommended to use upper cases for both such as System.IO. But if it is more than 2 such as Data Transfer Object > DTO then the suggestion is to use Pascal notation. So your class name should be CommentDto not CommentDTO.

Upvotes: 1

Related Questions