试图在外键上加入表,但输出不正确。 CRUD 也没有完全工作
Posted
技术标签:
【中文标题】试图在外键上加入表,但输出不正确。 CRUD 也没有完全工作【英文标题】:Trying to join table on foreign key, but output is incorrect. CRUD also not fully working 【发布时间】:2021-08-13 19:12:14 【问题描述】:这是我的代码:
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: </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>
AlbumTracks.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);
AlbumTracks.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: </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>
我应该解释一下ArtistId
是Albums
表的外键,AlbumId
是Tracks
表的外键。
艺术家数据正在传递到/Tracks
,但出现了问题,因为所有输出都是以字母 A 开头的艺术家。所以似乎每个艺术家的名字都被重复了很多次?
我的代码还有另一个问题,因为我注意到当我尝试从我也创建的 /AlbumTracks
页面添加轨道时,我收到重定向页面的“找不到页面”错误,即使该 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
【问题讨论】:
还有问题吗,还是你自己解决了? 好吧,我想出了一个“解决方法”,它至少表明数据库可以按照现状正确更新。但是对于用户来说,必须手动输入正确的AlbumId
值才能进行编辑显然并不理想。我真的更喜欢自动化解决方案。
【参考方案1】:
第一种方式:
当你进入Albums/AlbumTracks?id=361
页面时,你可以看到AlbumId
等于361的曲目列表。如果你在这个页面中发布表单,请求url仍然是Albums/AlbumTracks?id=361
。所以你在后处理程序中得到的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: </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
的两种方式。
【讨论】:
啊,太棒了,非常感谢。我不太清楚的事情是ElementAt(0)
的用途,以及为什么需要name=
?如果有人能告诉我那条线的伪代码会很棒,就像那条线到底在做什么/说什么?再次感谢。
模型绑定系统会通过匹配name
来绑定模型。 asp-for
将自动生成 name
和 id
元素,它会生成 name=Tracks.ElementAt(0).AlbumId
但它与模型属性不匹配。这就是您需要指定name
的原因。 ElementAt(0)
用于返回序列中指定索引处的元素。参考:docs.microsoft.com/en-us/dotnet/api/…以上是关于试图在外键上加入表,但输出不正确。 CRUD 也没有完全工作的主要内容,如果未能解决你的问题,请参考以下文章