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

Trying to join table on foreign key, but output is incorrect. CRUD also not fully working

这是我的代码:

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");
        }
    }
}

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 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 AlbumTracksModel : PageModel
    {
        private Chinook db;

        public AlbumTracksModel(Chinook injectedContext)
        {
            db = injectedContext;
        }
        public IEnumerable<Track> Tracks { get; set; }
        public void OnGetAsync(int id)
        {
            ViewData["Title"] = "Chinook Web Site - Tracks";
            Tracks = db.Tracks.Include(a => a.Album).Where(a => a.AlbumId == id);
        }

        [BindProperty]
        public Track Track { get; set; }

        public IActionResult OnPost(int id)
        {
            if (ModelState.IsValid)
            {
                db.Tracks.Add(Track);
                db.SaveChanges();
                return RedirectToPage("/Albums/AlbumTracks?id=" + id);
            }
            return Page();
        }

        public IActionResult DeleteTrack(int TrackId, int id)
        {
            var track = db.Tracks.Find(TrackId);

            if (track == null) return Page();

            db.Tracks.Remove(track);
            db.SaveChanges();
            return RedirectToPage("/Albums/AlbumTracks?id=" + id);
        }
    }
}

专辑Tracks.cshtml

@page
@using Project.Models
@model Project.Pages.AlbumTracksModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<div class="row">
    <h1 class="display-2">Tracks</h1>
    <table class="table">
        <thead class="thead-inverse">
            <tr>
                <th>Track ID</th>
                <th>Track name</th>
            </tr>
        </thead>

        <tbody>
            @foreach (Track track in Model.Tracks)
            {
                <tr>
                    <td>@track.TrackId</td>
                    <td>@track.Name</td>
                </tr>
            }
        </tbody>
    </table>
</div>
<div class="row">
    <p>Enter a name & ID 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>

我应该解释一下ArtistIdAlbumstable的外键,AlbumIdTracks[=的外键72=].

艺术家数据正在传送至 /Tracks,但出现了问题,因为所有输出都是以字母 A 开头的艺术家。所以似乎每个艺术家的名字都被重复了很多次应该吗?

我的代码还有另一个问题,因为我注意到当我尝试从我也创建的 /AlbumTracks 页面添加曲目时,我收到重定向的 'page not found' 错误页面,即使 URL 似乎有效。虽然添加了曲目。

提前感谢您的指点。

GitHub repo

编辑:我决定忘记添加来自 /Tracks 的曲目。我认为从 /AlbumTracks 添加它们更有意义。

Edit2:重定向问题现已解决。我需要做

        return RedirectToPage("/Albums/AlbumTracks", new {id = id });

所以现在我需要能够添加曲目作为下一张专辑的一部分。

Edit3:我实际上是这样工作的:

    <div><input asp-for="Track.Name" /></div>
    <div><input asp-for="Track.TrackId" /></div>
    <div><input asp-for="Track.AlbumId" /></div>

让用户手动输入他们想要添加曲目的专辑的 AlbumId 显然不理想。最好让系统直接从 URL 中获取 AlbumId,如

 https://localhost:5001/Albums/AlbumTracks?id=361

第一种方式:

当你进入Albums/AlbumTracks?id=361页面时,你可以看到AlbumId等于361的曲目列表。如果你post这个页面的表格,请求url 仍然是 Albums/AlbumTracks?id=361。因此,您在 post 处理程序中获得的 id 就是您想要的 AlbumId。像下面这样更改 AlbumTracks.cshtml.cs

public class AlbumTracksModel : PageModel
{
    //...
    public IEnumerable<Track> Tracks { get; set; }
    [BindProperty]
    public Track Track { get; set; }

    public IActionResult OnPost(int id)
    {
        Track.AlbumId = id;  //set the albumid by the request url...
        if (ModelState.IsValid)
        {
            db.Tracks.Add(Track);
            db.SaveChanges();
            return RedirectToPage("/Albums/AlbumTracks", new { id = id });
        }
        return RedirectToPage("/Albums/AlbumTracks", new { id = id });
    }

另一种方法 是您可以在页面加载时使用 AlbumId 设置输入。 AlbumTracks.cshtml 渲染了特定 AlbumId 的曲目,它们都拥有相同的 AlbumId。您可以在 AlbumTracks.cshtml:

中阅读下面的 AlbumId
@page
@using Project.Models
@model Project.Pages.AlbumTracksModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers    
<div class="row">
    <h1 class="display-2">Tracks</h1>
    <table class="table">
        //....
    </table>
</div>
 <div class="row">
    <p>Enter a name & TrackID for a new track:&nbsp;</p>
    <form method="POST">
        <div><input asp-for="Track.Name" /></div>
        <div><input asp-for="Track.TrackId" /></div>

        //add this....
        <div><input asp-for="Tracks.ElementAt(0).AlbumId" name="Track.AlbumId" /></div>
        <input type="submit" />
    </form>
</div>

这两种方式都可以获得 AlbumId.