首页 > 解决方案 > 如何自定义将列表转换为不同的类型?

问题描述

使用 Entity Framework 和 Razor 页面,我目前有一个系统,我将我的模型包装在视图模型中并将它们显示到屏幕上,我认为这是我应该在 MVVM 架构中做的事情。

但是,我在将“Foo”类型的列表转换为“FooView”时遇到了一些麻烦,但是将“Foo”类型的变量转换为“FooView”是可以的。这是代码:

学生班

public class Student
{
    public Student()
    {
        Id = null;
        FirstName = "";
        Surname = "";
        Age = 0;
        DateOfBirth = new DateTime();
        Results = new HashSet<Result>();
    }

    public Student(string firstName, string surname, DateTime dateOfBirth)
    {
        Id = null;
        FirstName = firstName;
        Surname = surname;
        DateOfBirth = dateOfBirth;
        Results = new HashSet<Result>();
    }

    public int? Id { get; set; }

    public string FirstName { get; set; }

    public string Surname { get; set; }

    public int Age { get; private set; }

    // Implement backing field
    private DateTime _dateOfBirth;
    public DateTime DateOfBirth
    {
        get => _dateOfBirth;

        set
        {
            // Set Age when date of birth is provided
            _dateOfBirth = value;
            Age = (DateTime.Today.Year - this._dateOfBirth.Year);
            if (_dateOfBirth.Date > DateTime.Today.AddYears(-this.Age)) this.Age--;
        }
    }

    public HashSet<Result> Results { get; set; }

    public static implicit operator StudentView(Student student)
    {
        return new StudentView(student);
    }

}

成功将学生项目投射到剃刀页面上的学生视图项目 WORKS

@foreach (var item in Model.Result)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => ((StudentView)item.Student).FullName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Score)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Grade)
        </td>
        <td>
            <a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
            <a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
            <a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
        </td>
    </tr>
}

尝试投射列表以键入“学生视图”失败

public async Task OnGetAsync()
{
    Student = await _context.Student.Cast<StudentView>().ToListAsync();
}

InvalidCastException:无法将“StudentManagerDemoCore.Models.Student”类型的对象转换为“StudentManagerDemoCore.ViewModels.StudentView”类型。

Index.cshtml.cs 中的 StudentManagerDemoCore.Pages.Teacher.ManageStudent.IndexModel.OnGetAsync()

Student = await _context.Student.Cast<StudentView>().ToListAsync();

我有一种感觉,我在这里缺少一些东西,但我不确定它是什么。该错误意味着我的投射方法存在问题,但这并不能解释为什么它有时会起作用。

有人知道我要去哪里错了吗?

标签: c#.net-coreentity-framework-core

解决方案


您有多种选择来解决您的问题。

第一个解决方案是手动执行以下操作:

await _context.Student.Select(student => new StudentView()
{
    Id = student.Id,
    //....
}

另一种解决方案是使用手动映射器来执行映射。一个静态函数,它接受 aStudent并将其转换为 aStudentView并返回它。您可以在其他地方重复使用它。

我建议的最佳解决方案是使用AutoMapper


推荐阅读