【问题标题】:Mapping CHILD collection to a separate DTO (asp net core API automapper projection)将 CHILD 集合映射到单独的 DTO(asp net core API automapper 投影)
【发布时间】:2021-10-22 07:37:45
【问题描述】:

我的第一个 StackOverflow 问题,请多多包涵,并提前感谢您的帮助! :)

究竟如何让我的 asp.net 核心控制器在父响应的 DTO 中响应子集合的 DTO?由于需要这种多对多关系情况的一些业务逻辑约束,我需要两个单独的 DTO。

尝试了自动映射器,并在我生命的最后两天研究这个无济于事。

我在 Controller 中尝试了以下操作,但总是得到一个空的子集合。如果我返回不适合多对多关系的实体类,我可以显示子集合。

我希望得到看起来像...的 JSON

[
{   prop : .., 
    prop: .., 
    collection[
              {
              prop:..,
              prop:..
              }
              ]
}
]

这就是我的控制器中的内容:

        public ActionResult<IEnumerable<LogEntryDto>> GetAllEntries()
    {
        var entryList = _context.Entries.ToList();

        return Ok(_mapper.Map<IEnumerable<RiskGetDto>>(entryList));
    }

我的 Automapper 配置文件类包含实体和 DTO 之间的简单映射

            CreateMap<LogEntry, LogEntryDto>();
            CreateMap<Tag, TagDto>();

我有以下课程

public class LogEntry
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public List<Tag> Tags { get; set; } = new List<Tag>();
}

还有一个

    public class Tag
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
    public List<LogEntry> LogEntries{ get; set; } = new List<LogEntry>();
}

以及每个类的以下 DTO

    public class LogEntryDto
{
    public string Name { get; set; }
    public string Description { get; set; }
    public List<Tag> Tags { get; set; } = new List<Tag>();
}

还有……

    public class TagDto
{
    public string Name { get; set; }
    public string Value { get; set; }
}

感谢您的帮助。

【问题讨论】:

  • 如果我尝试返回单个资源并映射所有属性,例如var entry = _context.Entries.Where(....).Select(mapping here including child collection.ToList()).FirstOrDefault();,我会得到我想要的数据形状。也许我只需要一种更聪明的方法来构建我的资源列表,然后再将其发送回返回映射的控制器。请对如何实现这一目标有任何想法?

标签: c# linq asp.net-core entity-framework-core automapper


【解决方案1】:

好的,以防万一有人通过此修复得到帮助。我的愚蠢错误是由于我缺乏 lambda 表达式里程(!!);

我需要像这样在服务类的 GetAllEntries() 方法中检索全部属性(注意 Tags 上的 ToList() 集合):

public List<Risk> GetAllEntries() 
        {
            var entryList = _context.Entries.Select(e=> new Risk 
            {
                Id = e.Id,
                RiskName = e.RiskName,
                RiskDescription = e.RiskDescription,
   ---->>>    **Tags = e.Tags.ToList()**
            }).ToList();

            return entryList;
        }

然后将其传递给控制器​​并像这样映射:

        [HttpGet]
        public ActionResult<List<LogEntryDto>> GetAllEntries()
        {
            var entries = _entryService.GetAllEntries();

            return Ok(_mapper.Map<List<LogEntryDto>>(entries));
        }

然后让 AutoMapper 用简单的映射配置文件发挥它的魔力...:

public EntriesProfile()
        {

            CreateMap<LogEntry, LogEntryDto>()
                .ForMember
                (dto => dto.EntryId,
                dbEntity => dbEntity.MapFrom(src => ....)
                .ReverseMap();

            CreateMap<Tag, TagDto>()
                .ForMember
                (dto => dto.Name,
                 dbEntity => dbEntity.MapFrom(src => src.Name))
                .ForMember
                (dto => dto.Value,
                 dbEntity => dbEntity.MapFrom(src => src.Value))
                .ReverseMap();
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-03
    • 1970-01-01
    • 2017-01-19
    • 1970-01-01
    相关资源
    最近更新 更多