You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单个Razor Page(非MVC)中关联并展示两个模型的数据

解决一对多关联及Razor Page数据展示问题

一、外键关联配置优化

你的模型已经基本符合EF Core一对多关系的要求,做两处优化可避免潜在问题:

  1. 显式标记外键:在Shot模型的导航属性上添加特性,明确关联的外键字段,让EF映射逻辑更清晰:
[Required]
public int ChildId { get; set; }
[ForeignKey(nameof(ChildId))]
public Child Child { get; set; }
  1. 初始化集合避免空引用:在Child模型构造函数中初始化Shots集合,防止后续访问时触发空引用异常:
public Child()
{
    Shots = new List<Shot>();
}

二、修复Details页面后端逻辑

你的OnGet方法存在两处问题:查询结果未赋值给Child属性,且无需单独声明Shot属性(关联的Shot数据已包含在Child的Shots集合中)。修改后代码如下:

using HealthyShots.Data;
using HealthyShots.Models;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;

namespace HealthyShots.Pages.Details
{
    public class DetailsModel : PageModel
    {
        private readonly ApplicationDbContext _db;

        public Child Child { get; set; }

        public DetailsModel(ApplicationDbContext db)
        {
            _db = db;
        }
        
        public void OnGet(int Id)
        {
            Child = _db.Child
                .Include(child => child.Shots)
                .FirstOrDefault(child => child.ChildId == Id);
        }
    }
}

三、修改Razor视图展示批量Shot数据

视图需遍历Child.Shots集合来展示所有免疫记录,同时修正若干细节错误:

@page
@model HealthyShots.Pages.Details.DetailsModel

@{
    ViewData["Title"] = "Immunization Details";
}

<h2>Details</h2>

@if (Model.Child != null)
{
    <div>
        <h4>Demographic Information</h4>
        <hr />

        <table class="table table-bordeless" style="width:100%">
            <tr>
                <td style="width: 10%">
                    <div class="mb-3">
                        <label asp-for="Child.ChildId"></label>
                        <input asp-for="Child.ChildId" disabled class="form-control"/>
                    </div>
                </td>
                <td style="width: 30%">
                    <div class="mb-3">
                        <label asp-for="Child.LastName"></label>
                        <input asp-for="Child.LastName" disabled class="form-control"/>
                    </div>
                </td>
                <td style="width: 30%">
                    <div class="mb-3">
                        <label asp-for="Child.FirstName"></label>
                        <input asp-for="Child.FirstName" disabled class="form-control"/>
                    </div>
                </td>
                <td style="width: 5%">
                    <div class="mb-3">
                        <label asp-for="Child.MiddleInitial"></label>
                        <input asp-for="Child.MiddleInitial" disabled class="form-control"/>
                    </div>
                </td>
                <td style="width: 25%">
                    <div class="mb-3">
                        <label asp-for="Child.BirthDate"></label>
                        <input asp-for="Child.BirthDate" type="date" disabled class="form-control"/>
                    </div>
                </td>
            </tr>
        </table>
        <table class="table table-bordeless" style="width:100%">
            <tr>
                <td style="width: 25%">
                    <div class="mb-3">
                        <label asp-for="Child.Addr1"></label>
                        <input asp-for="Child.Addr1" disabled class="form-control"/>
                    </div>
                </td>
                <td style="width: 25%">
                    <div class="mb-3">
                        <label asp-for="Child.Addr2"></label>
                        <input asp-for="Child.Addr2" disabled class="form-control"/>
                    </div>
                </td>
                <td style="width: 25%">
                    <div class="mb-3">
                        <label asp-for="Child.City"></label>
                        <input asp-for="Child.City" disabled class="form-control"/>
                    </div>
                </td>
                <td style="width: 5%">
                    <div class="mb-3">
                        <label asp-for="Child.State"></label>
                        <input asp-for="Child.State" disabled class="form-control"/>
                    </div>
                </td>
                <td style="width: 20%">
                    <div class="mb-3">
                        <label asp-for="Child.Zip"></label>
                        <input asp-for="Child.Zip" disabled class="form-control"/>
                    </div>
                </td>
            </tr>
        </table>
    <br />
    <br />

        <h4>Immunizations</h4>
        <hr />

        @if (Model.Child.Shots.Any())
        {
            <table class="table table-bordered" style="width:100%">
                <thead>
                    <tr>
                        <th style="width: 20%">@Html.DisplayNameFor(m => m.Child.Shots.First().Date)</th>
                        <th style="width: 20%">@Html.DisplayNameFor(m => m.Child.Shots.First().Dose)</th>
                        <th style="width: 60%">@Html.DisplayNameFor(m => m.Child.Shots.First().ShotDesc)</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var shot in Model.Child.Shots)
                    {
                        <tr>
                            <td>
                                <input asp-for="@shot.Date" type="date" disabled class="form-control"/>
                            </td>
                            <td>
                                <input asp-for="@shot.Dose" disabled class="form-control"/>
                            </td>
                            <td>
                                <input asp-for="@shot.ShotDesc" disabled class="form-control"/>
                            </td>
                        </tr>
                    }
                </tbody>
            </table>
        }
        else
        {
            <p>No immunization records found.</p>
        }

        <a asp-page="/Children/Index">Back to List</a>
    </div>
}
else
{
    <p>Child not found.</p>
    <a asp-page="/Children/Index">Back to List</a>
}

主要修改点:

  • 添加空值判断,避免空引用异常
  • 遍历Model.Child.Shots集合,展示所有免疫记录
  • 修正FirstName输入框缺失的disabled属性
  • 移除多余的语法符号
  • 添加空数据状态提示

内容的提问来源于stack exchange,提问作者MelB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 13:30:40