c# - 如何自定义将列表转换为不同的类型?
问题描述
使用 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();
我有一种感觉,我在这里缺少一些东西,但我不确定它是什么。该错误意味着我的投射方法存在问题,但这并不能解释为什么它有时会起作用。
有人知道我要去哪里错了吗?
解决方案
您有多种选择来解决您的问题。
第一个解决方案是手动执行以下操作:
await _context.Student.Select(student => new StudentView()
{
Id = student.Id,
//....
}
另一种解决方案是使用手动映射器来执行映射。一个静态函数,它接受 aStudent
并将其转换为 aStudentView
并返回它。您可以在其他地方重复使用它。
我建议的最佳解决方案是使用AutoMapper。
推荐阅读
- kdb - KDB/q count 行数按列的值分组
- algorithm - 以最小的损失量和最相似的空间打包矩形的算法(用于多用户视频室)
- c++ - SetDlgItemInt 不会更改嵌入资源的编辑框
- java - 如何有条件地“删除”或隐藏按钮?
- ios - 在 Swift 中带有变量的 NSLocalizedString 不起作用
- ios - 如何测试您自己的应用程序的更新 (iOS)
- javascript - 如何在 auth nuxt js 中添加过期令牌?
- python - 更改模型:
keras 在 model.summary() 输出中自动给出 - android - 使用 Kotlin 的 Firebase 云消息传递 Android
- apache-spark-sql - Spark SQL 中 OR 与 UNION 的性能对比