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

Blazor客户端如何在课程列表中显示科目名称而非Guid

解决方案:在Blazor中显示科目名称而非Guid

你的问题核心在于当前的实体模型没有建立Course和Subject之间的关联关系,导致存储的是Subject的Guid字符串,查询时无法直接获取科目名称。下面提供几种解决方案,从规范的实体设计到临时的前端映射,你可以根据需求选择:

方案一:规范实体关系(推荐)

这是最符合Entity Framework Core最佳实践的做法,通过外键和导航属性建立关联,让EF自动加载关联数据。

1. 修改Course模型(Shared项目)

替换原来的CourseSubject字符串字段为外键SubjectID,并添加导航属性:

public class Course {
    public Guid CourseID { get; set; }
    [Required]
    public string CourseCode { get; set; }
    [Required]
    public string CourseName { get; set; }
    // 外键:关联Subject的ID
    public Guid SubjectID { get; set; }
    // 导航属性:关联对应的Subject实体
    public Subject Subject { get; set; }
    public string CourseCredits { get; set; }
}

2. 更新数据库结构

打开Package Manager Console,执行以下命令迁移数据库(确保选中Server项目):

Add-Migration AddSubjectForeignKeyToCourse
Update-Database

这会自动在Courses表中添加SubjectID列,并删除原来的CourseSubject列(如果不需要保留的话)。

3. 修改CourseData查询逻辑(Server项目)

使用Include方法加载关联的Subject数据:

public IEnumerable<Course> GetAllCourses() {
    try {
        // 加载Course对应的Subject实体
        return db.Courses.Include(c => c.Subject).ToList();
    } catch {
        throw;
    }
}

4. 调整前端页面

  • 课程创建页面:下拉框绑定到SubjectID而非字符串:
    <select class="form-control" @bind="@course.SubjectID">
        <option value="">-- 选择科目 --</option>
        @foreach (var subject in subjectList) {
            <option value="@subject.SubjectID">@subject.SubjectName</option>
        }
    </select>
    
  • 课程列表页面:显示关联的科目名称:
    <td>@course.Subject?.SubjectName</td>
    
    用?.避免空引用异常(如果某个课程没有关联科目时)。

方案二:使用DTO传输数据(无需修改实体关联)

如果暂时不想调整数据库结构,可以创建一个数据传输对象(DTO),在后端查询时手动关联科目名称:

1. 创建CourseDto(Shared项目)

public class CourseDto {
    public Guid CourseID { get; set; }
    public string CourseCode { get; set; }
    public string CourseName { get; set; }
    public string SubjectName { get; set; }
    public string CourseCredits { get; set; }
}

2. 修改CourseData的查询方法(Server项目)

通过Join关联Subject表,返回DTO:

public IEnumerable<CourseDto> GetAllCourses() {
    try {
        return db.Courses.Join(
            db.Subjects,
            course => course.CourseSubject,
            subject => subject.SubjectID.ToString(),
            (course, subject) => new CourseDto {
                CourseID = course.CourseID,
                CourseCode = course.CourseCode,
                CourseName = course.CourseName,
                SubjectName = subject.SubjectName,
                CourseCredits = course.CourseCredits
            }
        ).ToList();
    } catch {
        throw;
    }
}

3. 调整控制器和前端

控制器返回CourseDto类型,前端页面也改为接收CourseDto数组,直接显示SubjectName即可。


方案三:前端手动映射(快速临时解决)

如果不想修改后端代码,可以在前端同时获取课程列表和科目列表,手动匹配名称:

修改课程列表页面(Client项目)

@page "/Courses/Courses"
@inject HttpClient Http
<h1>Courses</h1>
<p>
    <a href="/Courses/Create">Create New</a>
</p>
@if (courseList == null || subjectList == null) {
    <p><em>Loading...</em></p>
} else {
    <table class='table'>
        <thead>
            <tr>
                <th>Course Code</th>
                <th>Course Name</th>
                <th>Subject</th>
                <th>Credits</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var course in courseList) {
                // 匹配对应的科目名称
                var matchedSubject = subjectList.FirstOrDefault(s => s.SubjectID.ToString() == course.CourseSubject);
                <tr>
                    <td>@course.CourseCode</td>
                    <td>@course.CourseName</td>
                    <td>@(matchedSubject?.SubjectName ?? "未关联科目")</td>
                    <td>@course.CourseCredits</td>
                    <td>
                        <a href='/Courses/Edit/@course.CourseID'>Edit</a> |
                        <a href='/Courses/Delete/@course.CourseID'>Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
}
@functions {
    Course[] courseList;
    List<Subject> subjectList;
    protected override async Task OnInitializedAsync() {
        // 并行加载数据,提升性能
        var courseTask = Http.GetJsonAsync<Course[]>("/api/Courses/Courses");
        var subjectTask = Http.GetJsonAsync<List<Subject>>("api/Subjects/Subjects");
        await Task.WhenAll(courseTask, subjectTask);
        
        courseList = courseTask.Result;
        subjectList = subjectTask.Result;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:45:31