获取班级列表

创建GetList方法

在ClassService中创建GetList方法,用于获取班级列表视图。

代码如下:

public List<ClassViewModel> GetList()
{
    List<Class> classes = classRepo.GetList();
    List<ClassViewModel> classViewModels = new List<ClassViewModel>();
    foreach (var @class in classes)
    {
        classViewModels.Add(new ClassViewModel()
        {
            Id = @class.Id,
            Name = @class.Name,
            MajorName = @class.Major.Name,
            GradeName = @class.Grade.Name,            
        });
    }
    return classViewModels;
}

需要注意的是,虽然Class模型和ClassViewModel中均包含MajorIdGradeId,但是在显示班级列表时,并不需要这2个属性,因此可以忽略。

返回视图模型

在Index视图中返回列表视图模型。

代码如下:

public IActionResult Index()
{
    return View(classService.GetList());
}

创建Index视图

在Index视图中添加必要的元素,代码如下:

@{
    ViewBag.Title = "班级管理";
}
@model List<ClassViewModel>

<div>
    <a asp-action="Add" class="button is-primary mb-4">添加班级</a>
    <table class="table is-bordered is-striped is-hoverable is-fullwidth">
        <thead>
            <tr>
                <th>专业</th>
                <th>年级</th>
                <th>班级名称</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var clazz in Model)
            {
                <tr>
                    <td>@clazz.MajorName</td>
                    <td>@clazz.GradeName</td>
                    <td>@clazz.Name</td>
                    <td>
                        <a asp-action="Edit" asp-route-id="@clazz.Id" class="button is-warning">编辑</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
</div>

空引用异常

运行后来到Index页面,会输入如下错误:

An unhandled exception occurred while processing the request.
NullReferenceException: Object reference not set to an instance of an object.

这个错误产生的原因是因为在ClassService的GetList方法中,对ClassViewModel的MajorName和GradeName赋值时,使用的语句分别是:

MajorName = @class.Major.Name,
GradeName = @class.Grade.Name,

但是,在数据库表中,Classes只有IdNameMajorIdGradeId这4个字段,并没有包含导航Major和Grade的值。

如果想在查找时默认包含导航,就需要用到Include函数。

Include

先看原版语句,在BaseRepository中,它直接将数据返回,不做任何处理。

public List<T> GetList()
{
    return DbSet.ToList();
}

为了让数据附带导航的值,可以在DbSet后面添加Include方法。

当然,我们不能直接修改,而是在ClassRepo中新增新方法。

创建GetListWithMajorAndGrade方法

在ClassRepo添加GetListWithMajorAndGrade方法,通过Include方法表示获取数据时附带导航Major和Grade。

代码如下:

public List<Class> GetListWithMajorAndGrade()
{
    return DbSet.Include(c => c.Major).Include(c => c.Grade).ToList();
}

然后,将ClassService中调用的方法换成GetListWithMajorAndGrade。

public List<ClassViewModel> GetList()
{
    List<Class> classes = classRepo.GetListWithMajorAndGrade();
    List<ClassViewModel> classViewModels = new List<ClassViewModel>();
    foreach (var @class in classes)
    {
        classViewModels.Add(new ClassViewModel()
        {
            Id = @class.Id,
            Name = @class.Name,
            MajorName = @class.Major.Name,
            GradeName = @class.Grade.Name,
        });
    }
    return classViewModels;
}