如何在API控制器中手动映射Linq结果至AuthorDTO并关联NewsContents
问题描述
在API控制器中尝试手动将作者的文章列表映射至对应的DTO模型,使用AuthorDTO和NewsContentDTO展示作者详情及其关联文章,需要将GetHeroAuthor()返回的Linq结果中的所有NewsContents填充到AuthorDTO,返回包含作者详情及全部关联文章的DTO,但当前代码写法存在问题,需指导正确实现方式。
相关DTO代码
public class AuthorDTO { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public List<NewsContentDTO> NewsContents { get; set; } } public class NewsContentDTO { public int Id { get; set; } public string Category { get; set; } public string ContentTitle { get; set; } public AuthorDTO Author { get; set; } }
当前错误的控制器代码
var authors = _authorRepo.GetHeroAuthor(); AuthorDTO author = new AuthorDTO() { FirstName = authors.FirstName, LastName = authors.LastName NewsContents = New List<NewsContentDTO>() { Category = authors.NewsContents.Category, ContentTitle = authors.NewsContents.ContentTitle } }; return(author);
仓储返回的数据示例
{ "id": 2, "firstName": "My", "lastName": "Name", "newsContents": [ { "id": 2, "category": "Story", "contentTitle": "Shopping Trip" }, { "id": 3, "category": "Story", "contentTitle": "Rainy day" } ] }
解决方案
当前代码的问题包括:
- 语法错误:
LastName后缺少逗号,New应为小写new - 逻辑错误:
authors.NewsContents是列表集合,不能直接访问Category和ContentTitle属性,需要遍历集合逐个映射 - 潜在循环引用:
NewsContentDTO中的Author属性如果直接赋值会导致序列化时出现循环引用问题
正确的实现代码如下:
var authorEntity = _authorRepo.GetHeroAuthor(); var authorDto = new AuthorDTO() { Id = authorEntity.Id, FirstName = authorEntity.FirstName, LastName = authorEntity.LastName, // 遍历文章列表,逐个映射到NewsContentDTO NewsContents = authorEntity.NewsContents.Select(nc => new NewsContentDTO() { Id = nc.Id, Category = nc.Category, ContentTitle = nc.ContentTitle, // 避免循环引用,这里不赋值Author属性,或者只赋值必要的基础属性(如Id) // Author = new AuthorDTO { Id = authorEntity.Id, FirstName = authorEntity.FirstName } }).ToList() }; return authorDto;
补充说明
- 建议使用
Select配合ToList()来完成集合的映射,这是LINQ中处理集合转换的标准方式 - 若不需要在文章DTO中返回作者信息,可直接删除
NewsContentDTO中的Author属性,彻底避免循环引用 - 如果项目规模较大,推荐使用AutoMapper这类对象映射库来简化手动映射的代码,减少重复劳动
内容的提问来源于stack exchange,提问作者Alevel
相关产品推荐
相关产品推荐

