Reputation: 2356
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
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