试图从数据库表中读取,但输出不正确
Posted
技术标签:
【中文标题】试图从数据库表中读取,但输出不正确【英文标题】:Trying to read from database table, but output is incorrect 【发布时间】:2021-08-14 16:07:51 【问题描述】:这是我的代码:
tracks.cshtml
@page
@using Project.Models
@model Project.Pages.TracksModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<div class="row">
<h1 class="display-2">Tracks</h1>
<table class="table">
<thead class="thead-inverse">
<tr>
<th>Artist name</th>
<th>Album name</th>
<th>Track ID</th>
<th>Track name</th>
</tr>
</thead>
<tbody>
@foreach (Track track in Model.Tracks)
<tr>
<td>@html.DisplayFor(modelArtists => track.Artist.Name)</td>
<td>@Html.DisplayFor(modelAlbums => track.Album.Title)</td>
<td>@track.TrackId</td>
<td>@track.Name</td>
<td><a asp-page="/Tracks/Details" asp-route-id="@track.TrackId">Details</a></td>
<td><a asp-page="/Tracks/Edit" asp-route-id="@track.TrackId">Edit</a></td>
<td><a asp-page="/Tracks/Delete" asp-route-id="@track.TrackId">Delete</a></td>
</tr>
</tbody>
</table>
</div>
<div class="row">
<p>Enter a name & TrackID (over 3510) for a new track: </p>
<form method="POST">
<div><input asp-for="Track.Name" /></div>
<div><input asp-for="Track.TrackId" /></div>
<input type="submit" />
</form>
</div>
<div>
<a asp-page="/Index">Home</a>
</div>
tracks.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Project.Models;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Project.Pages
public class TracksModel : PageModel
private Chinook db;
public TracksModel(Chinook injectedContext)
db = injectedContext;
public IEnumerable<Track> Tracks get; set;
public void OnGetAsync()
ViewData["Title"] = "Chinook Web Site - Tracks";
Tracks = db.Tracks.Include(a => a.Album)
.Include(a => a.Artist);
[BindProperty]
public Track Track get; set;
public IActionResult OnPost()
if (ModelState.IsValid)
db.Tracks.Add(Track);
db.SaveChanges();
return RedirectToPage("/tracks");
return Page();
public IActionResult DeleteTrack(int TrackId)
var track = db.Tracks.Find(TrackId);
if (track == null) return Page();
db.Tracks.Remove(track); db.SaveChanges(); return RedirectToPage("/tracks");
GitHub repo
出现问题,因为页面似乎多次重复艺术家姓名,以至于显示的所有艺术家姓名都以字母 A 开头。我应该说我设置数据库的方式, ArtistId
是Album
表的外键,AlbumId
是Tracks
表的外键。
也许我需要像.Where(a => a.AlbumId == Tracks.AlbumId)
和.Where(a => a.ArtistId == Album.ArtistId)
这样的子句?我试图写这样的东西,但我一定是做错了,因为它完全阻止了曲目的显示。请问有什么帮助吗? TIA
编辑:我注意到虽然我的专辑标题是从Album
表中加入的,但我的艺术家姓名不是,即使方法基本相同。我突然想到Album
表直接连接到Track
表(通过AlbumId
外键),Artist
表不是。它只是通过Album
表与“Track”表间接相关。
Artist
----Album
----Track
Edit2:有人告诉我在这种情况下不需要Where
,我应该使用“ThenInclude”,所以我现在有了
public void OnGetAsync()
ViewData["Title"] = "Chinook Web Site - Tracks";
Tracks = db.Tracks.Include(a => a.Album).ThenInclude(b => b.Artist).ToList();
但它仍然会导致完全相同的错误。
【问题讨论】:
也许您可以提供静态 html 结果来检查问题所在。 对不起,我不太明白你的意思。但是,如果您查看此屏幕截图,也许您会发现 AC/DC 发布的版本太多了。 i.imgur.com/fYMZXFL.jpg 这是不正确的。艺术家姓名以某种方式被错误地重复。 您是否验证了数据库中的外键是正确的?因为看起来 Aerosmith 也被称为 ACDC。或者您是否在循环之前对其进行了调试并验证了它是否正确? 抱歉,我不太清楚你的意思?我可以让艺术家姓名在我网站的其他页面上正常显示,这只是我遇到此问题的这一页。 【参考方案1】:重点在Context.Chinook.cs
protected override void OnModelCreating(ModelBuilder modelBuilder)
....
modelBuilder.Entity<Track>()
.ToTable("tracks")
.HasOne(mtype => mtype.Artist)
.WithMany(trk => trk.Tracks)
.HasForeignKey(mtype => mtype.AlbumId)
.HasForeignKey(mtype => mtype.GenreId)
.HasForeignKey(mtype => mtype.MediaTypeId)
.OnDelete(DeleteBehavior.NoAction);
HasForeignKey链如果与上述关系(1到n,n到1,1到1)无关,则必须分开。 以下是我修改的代码。
Context.Chinook.cs
protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.Entity<Album>()
.ToTable("albums")
.HasOne(al => al.Artist)
.WithMany(ar => ar.Albums)
.HasForeignKey(al => al.ArtistId);
modelBuilder.Entity<Artist>().ToTable("artists");
modelBuilder.Entity<Media_type>()
.ToTable("media_types")
.HasKey(c => c.MediaTypeId);
modelBuilder.Entity<Genre>().ToTable("genres");
modelBuilder.Entity<Track>()
.ToTable("tracks")
.HasOne(trk => trk.Album)
.WithMany(trk => trk.Tracks)
.HasForeignKey(trk => trk.AlbumId)
.OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<Track>()
.ToTable("tracks")
.HasOne(trk => trk.Genre)
.WithMany(trk => trk.Tracks)
.HasForeignKey(trk => trk.GenreId);
modelBuilder.Entity<Track>()
.ToTable("tracks")
.HasOne(trk => trk.Media_type)
.WithMany(trk => trk.Tracks)
.HasForeignKey(mtype => mtype.MediaTypeId);
实体.艺术家
public class Artist
public int ArtistId get; set;
public string Name get; set;
public ICollection<Album> Albums get; set;
实体.流派
public class Genre
public int GenreId get; set;
public string Name get; set;
public ICollection<Track> Tracks get; set;
Entities.Media_type
public class Media_type
public int MediaTypeId get; set;
public string Name get; set;
public ICollection<Track> Tracks get; set;
Entity.Track
public class Track
public int TrackId get; set;
public string Name get; set;
public int? AlbumId get; set;
public int? MediaTypeId get; set;
public int? GenreId get; set;
public string Composer get; set;
public int? Milliseconds get; set;
public int? Bytes get; set;
public int? UnitPrice get; set;
public Album Album get; set;
public Genre Genre get; set;
public Media_type Media_type get; set;
WebApp.tracks.cshtml.cs
public void OnGetAsync()
ViewData["Title"] = "Chinook Web Site - Tracks";
Tracks = db.Tracks
.Include(a => a.Album)
.ThenInclude(a => a.Artist);
WebApp.tracks.cshtml
<tbody>
@foreach (Track track in Model.Tracks)
<tr>
<td>@Html.DisplayFor(modelArtists => track.Album.Artist.Name)</td>
<td>@Html.DisplayFor(modelAlbums => track.Album.Title)</td>
<td>@track.TrackId</td>
<td>@track.Name</td>
<td><a asp-page="/Tracks/Details" asp-route-id="@track.TrackId">Details</a></td>
<td><a asp-page="/Tracks/Edit" asp-route-id="@track.TrackId">Edit</a></td>
<td><a asp-page="/Tracks/Delete" asp-route-id="@track.TrackId">Delete</a></td>
</tr>
</tbody>
参考: Entity Framework Core Relationships
【讨论】:
以上是关于试图从数据库表中读取,但输出不正确的主要内容,如果未能解决你的问题,请参考以下文章