ASP.NET中如何通过中间表关联Movie与Studio表?
解决ASP.NET中Movie与Studio的间接关联问题
一、先确认EF Core关联加载的正确性
你当前的Include链式调用语法是正确的,但如果视图中无法获取Studio数据,可能是视图遍历关联数据的方式有误。不过更推荐使用ViewModel封装所需数据,既能避免视图中多层嵌套访问关联对象,也能提升查询效率。
二、创建专用ViewModel
定义ViewModel来整合Movie及其关联的Studio信息(注意一个Movie可能对应多个Studio,需做去重处理):
public class MovieWithStudiosViewModel { public int MovieId { get; set; } public string MovieName { get; set; } public string Description { get; set; } public double Price { get; set; } public string ImageURL { get; set; } // 按需添加其他Movie需要展示的字段 // 去重后的关联Studio列表 public List<StudioViewModel> Studios { get; set; } = new List<StudioViewModel>(); } public class StudioViewModel { public int Id { get; set; } public string StudioName { get; set; } public string Owner { get; set; } }
三、修改控制器查询逻辑
用LINQ投影将数据映射到ViewModel,同时处理Studio去重:
public async Task<IActionResult> Index() { var moviesWithStudios = await _context.Movie .Include(m => m.Cinema) .Include(m => m.Movie_Producers) .ThenInclude(mp => mp.Producer) .ThenInclude(p => p.Studio) .Select(m => new MovieWithStudiosViewModel { MovieId = m.Id, MovieName = m.Name, Description = m.Description, Price = m.Price, ImageURL = m.ImageURL, // 提取关联Studio并去重 Studios = m.Movie_Producers? .Where(mp => mp.Producer?.Studio != null) .Select(mp => new StudioViewModel { Id = mp.Producer.Studio.Id, StudioName = mp.Producer.Studio.Studio_Name, Owner = mp.Producer.Studio.Owner }) .DistinctBy(s => s.Id) // .NET 6+支持,按StudioID去重 .ToList() ?? new List<StudioViewModel>() }) .ToListAsync(); return View(moviesWithStudios); }
若项目基于.NET 5及以下(无DistinctBy),可改用GroupBy实现去重:
Studios = m.Movie_Producers? .Where(mp => mp.Producer?.Studio != null) .Select(mp => new StudioViewModel { Id = mp.Producer.Studio.Id, StudioName = mp.Producer.Studio.Studio_Name, Owner = mp.Producer.Studio.Owner }) .GroupBy(s => s.Id) .Select(g => g.First()) .ToList() ?? new List<StudioViewModel>()
四、修改视图绑定ViewModel
将视图模型类型改为IEnumerable<MovieWithStudiosViewModel>,然后展示数据:
@model IEnumerable<MovieWithStudiosViewModel> @{ ViewData["Title"] = "Movies"; } <h1>Movies</h1> @foreach (var movie in Model) { <div class="card mb-3"> <img src="@movie.ImageURL" class="card-img-top" alt="@movie.MovieName"> <div class="card-body"> <h5 class="card-title">@movie.MovieName</h5> <p class="card-text">@movie.Description</p> <p class="card-text">Price: $@movie.Price</p> @if (movie.Studios.Any()) { <h6>关联制片厂:</h6> <ul> @foreach (var studio in movie.Studios) { <li>@studio.StudioName (负责人:@studio.Owner)</li> } </ul> } </div> </div> }
五、额外注意事项
- 确保
Movie_Producers、Producer和Studio的外键关系在数据库中配置正确,可通过Where过滤空值避免异常 - ViewModel中只保留需要展示的字段,减少不必要的数据传输
内容的提问来源于stack exchange,提问作者md317
相关产品推荐
相关产品推荐

