You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core中Select()在ThenInclude()内不生效,如何映射TheaterDTO剔除冗余Screenings列表

解决方案

第一步:补充所需DTO定义

你只定义了TheaterDTO,还需要补充对应的ScreeningDTO和MovieDTO,避免直接返回实体类触发EF Core的关联修复逻辑导致冗余数据:

// 场次DTO
public class ScreeningDTO
{
    public DateTime Time { get; set; }
    public TheaterDTO Theater { get; set; }
}

// 电影DTO
public class MovieDTO
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Body { get; set; }
    public string Dir { get; set; }
    public string Pic { get; set; }
    public ICollection<ScreeningDTO> Screenings { get; set; }
}

第二步:重写查询逻辑,使用投影查询

不要用Include加载实体导航属性,直接通过Select投影到DTO,EF Core会自动生成最简SQL,仅查询你需要的字段,不会拉取Theater下冗余的Screenings列表:

[HttpGet]
[Route("{movieId}")]
public MovieDTO GetMovieById(Guid movieId)
{
    return _context.Movies
        .Where(m => m.Id == movieId)
        .Select(m => new MovieDTO
        {
            Id = m.Id,
            Name = m.Name,
            Body = m.Body,
            Dir = m.Dir,
            Pic = m.Pic,
            Screenings = m.Screenings.Select(s => new ScreeningDTO
            {
                Time = s.Time,
                Theater = new TheaterDTO
                {
                    Name = s.Theater.Name,
                    Address = s.Theater.Address
                }
            }).ToList()
        })
        .FirstOrDefault();
}

可选简化方案:使用AutoMapper

如果不想每次手动写投影逻辑,可以引入AutoMapper,配置好实体和DTO的映射关系后,直接用ProjectTo方法即可实现相同效果:

// 需先注入IMapper实例
[HttpGet]
[Route("{movieId}")]
public MovieDTO GetMovieById(Guid movieId)
{
    return _context.Movies
        .Where(m => m.Id == movieId)
        .ProjectTo<MovieDTO>(_mapper.ConfigurationProvider)
        .FirstOrDefault();
}

原问题原因说明

  1. 之前的接口返回类型为实体类Movie,即使你不主动加载Theater的Screenings,EF Core的关联修复功能也会把已经加载的Screening对象自动关联到对应的Theater的Screenings集合中,导致冗余。
  2. 之前的查询逻辑错误:从Screenings表查询,且筛选条件写的是m => movieId == m.Id,是用电影ID匹配场次ID,完全查不到正确数据。

内容的提问来源于stack exchange,提问作者user321

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 18:03:03