首页 > 解决方案 > 实体框架将嵌套实体映射到视图模型

问题描述

这是我的视图模型。实体的结构完全相同,只是名称没有 ViewModel

public class CelulaViewModel
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public int? CheckListId { get; set; }
    public CheckList CheckList { get; set; }
}

public class CheckListViewModel
{
    public int Id { get; set; }
    public string Nome { get; set; }        
    public IList<CheckListGrupoViewModel> Grupos { get; set; }

    public IList<CelulaViewModel> Celulas { get; set; }
}

public class CheckListGrupoViewModel
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public IList<CheckListGrupoItemViewModel> Items { get; set; }
}

public class CheckListGrupoItemViewModel
{
    public int Id { get; set; }
    public string Nome { get; set; }

    public string Value { get; set; }
}

这是我的页面模型

    public class IndexModel : PageModel
    {
        private readonly DatabaseContext _context;

        public IndexModel(DatabaseContext context)
        {
            _context = context;
        }

        #region Properties    
        public CelulaViewModel Celula { get; set; }


        #endregion

        #region Handlers
        public IActionResult OnGet(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            Celula = _context.Celulas
                .Include(c => c.CheckList)
                .ThenInclude(cl => cl.Grupos)
                .ThenInclude(cl => cl.Items)
                .Where(c => c.Automated)
                .Select(c => new CelulaViewModel
                {
                    Id = c.Id,
                    Nome = c.Nome,
                    CheckListId = c.CheckListId,
                    CheckList = new CheckListViewModel
                    {
                        Id = c.CheckList.Id,
                        Nome = c.CheckList.Nome,
                        Grupos = new List<CheckListGrupoViewModel>
                        {
                           // ?? How to map the list in here?
                        }
                    }
                })
                .FirstOrDefault(c => c.Id == id);

            if (Celula == null)
            {
                return NotFound();
            }

            return Page();
        }

        public IActionResult OnPost(string[] id)
        {
            return RedirectToPage("../Index");
        }
        #endregion
    }

如您所见,我正在尝试将实体和子实体映射到视图模型和子视图模型。问题在于尝试使用 ICollections 进行操作时。我不知道如何在 lambda 表达式中处理这个问题

标签: c#asp.net-core.net-coreasp.net-core-mvcasp.net-core-3.0

解决方案


这是我使用自动映射器映射复杂数据的方式

var vm = new IndexViewModel
{
  Posts = _mapper.Map<IEnumerable<Post>, IEnumerable<PostListViewModel>>(posts)
}

以下是相关实体。我有 Post 和 PostListViewModel

public class Post : BaseEntity
{
    public string Title { get; set; }
    public string ShortDescription { get; set; }
    public string Content { get; set; }
    public PostStatus PostStatus { get; set; }
    public int Views { get; set; }
    public virtual User User { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }
    public virtual Media Medias { get; set; }
}

public class PostListViewModel
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string ShortDescription { get; set; }
    public string Content { get; set; }
    public string Tags { get; set; }
    public string Categories { get; set; }
    public PostStatus PostStatus { get; set; }
    public int Views { get; set; }
    public DateTime DateCreated { get; set; }
    public Media Medias { get; set; }
}

和简介

public class PostProfile : Profile
{
    public PostProfile()
    {
        CreateMap<Post, PostViewModel>(MemberList.None).ReverseMap();
    }
}

然后在我的 Startup.cs

services.AddAutoMapper();

另一个样本(复杂的一个)

public class CommentProfile : Profile
    {
        public CommentProfile()
        {
            CreateMap<Comment, CommentDto>(MemberList.None).ReverseMap();
        }
    }

    public class Comment : BaseEntity
    {
        public string Content { get; set; }
        public virtual Comment ParentComment { get; set; }
        public virtual Post Post { get; set; }
        public virtual User? User { get; set; }
        public CommentStatus CommentStatus { get; set; }
    }

    public class CommentDto
    {
        public int Id { get; set; }
        public Guid UniqeId { get; set; }
        public string Content { get; set; }
        public Comment ParentComment { get; set; }
        public CommentStatus CommentStatus { get; set; }
        public DateTime DateCreated { get; set; }
    }

这是我映射所有数据的方式

    var comments = await _unitOfWork.Repository<Comment>().Query()
                .Include(x => x.User)
                .Include(c => c.Post)
                .Select(x => new CommentViewModel
                {
                    User = _mapper.Map<User, UserViewModel>(x.User),
                    Post = _mapper.Map<Post, PostViewModel>(x.Post),
                    Comment = _mapper.Map<Comment, CommentDto>(x),
                })
                .ToListAsync();

推荐阅读