我首先使用具有相同类型的子父
的代码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();
答案 0 :(得分:1)
由于Comment
和CommentDTO
中的媒体资源名称相同,您只需要指示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
。