试图从数据库表中读取,但输出不正确

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:&nbsp;</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 开头。我应该说我设置数据库的方式, ArtistIdAlbum表的外键,AlbumIdTracks表的外键。

也许我需要像.Where(a =&gt; a.AlbumId == Tracks.AlbumId).Where(a =&gt; 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

【讨论】:

以上是关于试图从数据库表中读取,但输出不正确的主要内容,如果未能解决你的问题,请参考以下文章

从 Cassandra 填充缓存的正确方法

试图在外键上加入表,但输出不正确。 CRUD 也没有完全工作

从管道读取时返回的数据不正确

从 Excel 工作表中读取日期时间值

从天蓝色表中读取行时为空值

从多个表中检索多个列不存在或匹配行集(mysql php)