ASP.NET Core问答Razor Pages构建问题:外键与页面逻辑排查
解决一对多模型外键及页面逻辑问题
一、先搞定外键配置的常见坑
- 确保Answer模型的外键命名符合EF约定:定义
public int QuestionId { get; set; },同时添加导航属性public Question Question { get; set; };Question模型里要初始化集合导航属性:public ICollection<Answer> Answers { get; set; } = new List<Answer>(); - 若需明确外键关联,给导航属性加
[ForeignKey(nameof(QuestionId))]特性,避免EF自动生成错误的外键字段 - 用Fluent API配置的话,在DbContext的
OnModelCreating方法里添加:modelBuilder.Entity<Answer>() .HasOne(a => a.Question) .WithMany(q => q.Answers) .HasForeignKey(a => a.QuestionId) .OnDelete(DeleteBehavior.Cascade);
二、彻底抛弃静态变量,用Query参数直接查询
静态变量是全局共享的,多用户访问必出数据串用问题,完全不能用来存储用户级的QuestionId。正确做法:
- 在answers页面的后置代码(如
Answers.cshtml.cs)里,直接从请求Query中获取QuestionId并查询数据:public async Task OnGetAsync() { if (int.TryParse(Request.Query["questionId"], out int questionId)) { CurrentQuestion = await _context.Questions .Include(q => q.Answers) // 关联加载答案 .FirstOrDefaultAsync(q => q.Id == questionId); } } - 添加答案时,直接从Query参数拿到QuestionId赋值给新Answer,保存后必须重定向回answers页面,而非直接返回视图:
public async Task<IActionResult> OnPostAddAnswerAsync(Answer answer) { if (int.TryParse(Request.Query["questionId"], out int questionId)) { answer.QuestionId = questionId; _context.Answers.Add(answer); await _context.SaveChangesAsync(); // 重定向带参数,强制页面重新加载最新数据 return RedirectToPage("Answers", new { questionId = questionId }); } return RedirectToPage("Index"); }
三、解决TempData导致的重复显示和不更新问题
TempData设计用于跨请求临时存储一次性提示信息,不能用来存业务数据(如问题、答案列表):
- 删掉用TempData存储Question或Answers集合的逻辑,每次页面加载都直接从数据库查询最新数据,通过
Include关联加载答案确保数据完整 - 直接用Query参数传递QuestionId,避免依赖TempData的持久化特性导致旧数据残留
四、页面渲染注意点
在answers.cshtml中,直接绑定后台的CurrentQuestion对象渲染内容:
<h3>@Model.CurrentQuestion.Title</h3> <p>@Model.CurrentQuestion.Content</p> <h4>所有答案</h4> @foreach (var answer in Model.CurrentQuestion.Answers) { <div class="answer-item"> <p>@answer.Content</p> </div> } <!-- 添加答案表单,携带questionId参数 --> <form method="post" asp-page-handler="AddAnswer" asp-route-questionId="@Model.CurrentQuestion.Id"> <textarea asp-for="NewAnswer.Content" required></textarea> <button type="submit">提交答案</button> </form>
内容的提问来源于stack exchange,提问作者Fernando Fiore
相关产品推荐
相关产品推荐

