在MVC中返回一个列表会导致错误
本文关键字:列表 一个 错误 MVC 返回 | 更新日期: 2023-09-27 17:52:16
我正在尝试返回教育系统中的时间表列表。我有一个时间表模型在我的项目与此属性:
public partial class Schedule
{
public Schedule()
{
this.ClassTimes = new HashSet<ClassTime>();
this.Scores = new HashSet<Score>();
}
public int Id { get; set; }
public int TeacherId { get; set; }
public int LessonId { get; set; }
public int ClassId { get; set; }
public int DegreeId { get; set; }
public int FacultyId { get; set; }
public int SemesterId { get; set; }
public int MajorId { get; set; }
public System.DateTime DateOfExame { get; set; }
public string Capacity { get; set; }
public string locationOfExame { get; set; }
public virtual Class Class { get; set; }
public virtual ICollection<ClassTime> ClassTimes { get; set; }
public virtual Degree Degree { get; set; }
public virtual Faculty Faculty { get; set; }
public virtual Lesson Lesson { get; set; }
public virtual Major Major { get; set; }
public virtual ICollection<Score> Scores { get; set; }
public virtual Semester Semester { get; set; }
public virtual Teacher Teacher { get; set; }
}
所以在这个模型中,我保存了我的实体的id
,例如major, teacher, lesson等。所以我得把我的日程表还给你。所以我要把我的实体的id
转换成那个实体的名字。因此,我在MVC项目中设计了一个时间表控制器,如下所示:
private readonly ScheduleRepositor obj = new ScheduleRepositor();
public ActionResult Index()
{
var list=new List<SchedulePresentation>();
ClassRepository objclassrep=new ClassRepository();
DegreeRepositor objdegreerep=new DegreeRepositor();
FacultyRepositor objfactulyrep=new FacultyRepositor();
LessonRepository objLessonRep=new LessonRepository();
MajorRepository objmajorrep=new MajorRepository();
SemesterRepositor objsemesterrep=new SemesterRepositor();
TeacherRepositor objteacherrep=new TeacherRepositor();
DateConverter objdateconverte = new DateConverter();
List<Schedule> model = obj.GetLessonlist();
foreach (var t in model)
{
SchedulePresentation objpres=new SchedulePresentation();
objpres.Capacity = t.Capacity;
objpres.DateOfExam = objdateconverte.ConvertToPersianToShow(t.DateOfExame);
objpres.className = objclassrep.FindClassById(t.ClassId).ClassName;
objpres.degreeName = objdegreerep.FindDegreeById(t.DegreeId).DegreeName;
objpres.examLocation = t.locationOfExame;
objpres.facultyName = objfactulyrep.FindFacultyById(t.FacultyId).FacultyName;
objpres.lessonName = objLessonRep.FindLessonById(t.LessonId).LessonName;
objpres.majorName = objmajorrep.FindMajorById(t.MajorId).MajorName;
objpres.semesterName = objsemesterrep.FindSemesterById(t.SemesterId).SemesterName;
objpres.teacherName = objteacherrep.FindTeacherById(t.TeacherId).Name + " " +
objteacherrep.FindTeacherById(t.TeacherId).LastName;
list.Add(objpres);
}
return View(list);
}
所以我只是为每个实体创建一个存储库,通过id返回我的实体名称。
我为我的时间表创建了一个表示类,将id
转换为我的实体的名称,如下所示:
public class SchedulePresentation
{
public string teacherName { set; get; }
public string lessonName { set; get; }
public string className { set; get; }
public string degreeName { set; get; }
public string facultyName { set; get; }
public string semesterName { set; get; }
public string majorName { set; get; }
public string DateOfExam { set; get; }
public string Capacity { set; get; }
public string examLocation { set; get; }
}
我有两个问题。我的解决方案中有4个项目:
- DomainClass
- <
- 库/gh>MVC项目
这是一个好方法,我转换这些Id到他们的名字在MVC层,或者是更好地使一个存储库或创建一个模型的时间表列表?
在最后一行,当我想返回我的列表时,我得到了这个错误:
传入字典的模型项的类型是'System.Collections.Generic.List
1[EducationMVC.PresentationClass.SchedulePresentation]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable
1[DomainClasses.Schedule]'.
MVC视图代码
@model IEnumerable<DomainClasses.Schedule>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.TeacherId)
</th>
<th>
@Html.DisplayNameFor(model => model.LessonId)
</th>
<th>
@Html.DisplayNameFor(model => model.ClassId)
</th>
<th>
@Html.DisplayNameFor(model => model.DegreeId)
</th>
<th>
@Html.DisplayNameFor(model => model.FacultyId)
</th>
<th>
@Html.DisplayNameFor(model => model.SemesterId)
</th>
<th>
@Html.DisplayNameFor(model => model.MajorId)
</th>
<th>
@Html.DisplayNameFor(model => model.DateOfExame)
</th>
<th>
@Html.DisplayNameFor(model => model.Capacity)
</th>
<th>
@Html.DisplayNameFor(model => model.locationOfExame)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.TeacherId)
</td>
<td>
@Html.DisplayFor(modelItem => item.LessonId)
</td>
<td>
@Html.DisplayFor(modelItem => item.ClassId)
</td>
<td>
@Html.DisplayFor(modelItem => item.DegreeId)
</td>
<td>
@Html.DisplayFor(modelItem => item.FacultyId)
</td>
<td>
@Html.DisplayFor(modelItem => item.SemesterId)
</td>
<td>
@Html.DisplayFor(modelItem => item.MajorId)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateOfExame)
</td>
<td>
@Html.DisplayFor(modelItem => item.Capacity)
</td>
<td>
@Html.DisplayFor(modelItem => item.locationOfExame)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
@Html.ActionLink("Details", "Details", new { id=item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
您的视图可能有一个像这样的强类型模型
@model IEnumerable<DomainClasses.Schedule>
但是您返回的是List<SchedulePresentation>
。
一个解决方案是将模型行改为:@model IEnumerable<SchedulePresentation>
.
问题的答案就在错误信息中:
传入字典的模型项类型为'System.Collections.Generic.List
1[EducationMVC.PresentationClass.SchedulePresentation]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable
1[DomainClasses.Schedule]'.
似乎这个方法对应的视图(默认情况下是控制器的Index视图)期望一个类型为IEnumerable<Schedule>
的模型。
如果您希望发送List<SchedulePresentation>
,请将视图中的模型类型更改为IEnumerable<SchedulePresentation>
。
提示:在您的视图中,第一行的格式应该是:
@model IEnumerable<DomainClasses.Schedule>
可以这样修改:
@model IEnumerable<EducationMVC.PresentationClass.SchedulePresentation>
答案就在编译器报告的错误中。你传递给视图一个特定类型的模型对象(SchedulePresentation
),当视图期望一个Schedule
类型的模型对象。
特别是以下几行:
List<Schedule> model = obj.GetLessonlist();
foreach (var t in model)
{
SchedulePresentation objpres=new SchedulePresentation();
objpres.Capacity = t.Capacity;
objpres.DateOfExam = objdateconverte.ConvertToPersianToShow(t.DateOfExame);
objpres.className = objclassrep.FindClassById(t.ClassId).ClassName;
objpres.degreeName = objdegreerep.FindDegreeById(t.DegreeId).DegreeName;
objpres.examLocation = t.locationOfExame;
objpres.facultyName = objfactulyrep.FindFacultyById(t.FacultyId).FacultyName;
objpres.lessonName = objLessonRep.FindLessonById(t.LessonId).LessonName;
objpres.majorName = objmajorrep.FindMajorById(t.MajorId).MajorName;
objpres.semesterName = objsemesterrep.FindSemesterById(t.SemesterId).SemesterName;
objpres.teacherName = objteacherrep.FindTeacherById(t.TeacherId).Name + " " +
objteacherrep.FindTeacherById(t.TeacherId).LastName;
list.Add(objpres);
}
你正在创建一个List<Schedule>
,但是你添加了类型为SchedulePresentation
的对象,当你的视图中指定的模型期望类型为IEnumerable<DomainClasses.Schedule>
。因此,会出现以下错误:
传入字典的模型项类型为'System.Collections.Generic.List
1[EducationMVC.PresentationClass.SchedulePresentation]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable
1[DomainClasses.Schedule]'.
要解决这个问题,将模型行更改为@model IEnumerable<SchedulePresentation>
。
关于您的第一个问题,我想说MVC控制器是从存储库返回的信息中提取信息的正确位置,并将其放在视图模型(您的SchedulePresentation
类)中。然而,您发布的代码将导致大量的数据库查询——对于日程安排中的每个项目,您最终将需要8个额外的查询来获取相关的项目。在一个有20个项目的时间表中,这是一个额外的160个数据库查询,以获得你可能已经包括的东西。
您已经标记了此[entity-framework]
,因此我将假设您正在使用它从数据库中获取Schedule
项。而不是使用项目的id,使用实际的属性:
for (var t in model) {
SchedulePresentation objpres=new SchedulePresentation();
objpres.Capacity = t.Capacity;
objpres.DateOfExam = objdateconverte.ConvertToPersianToShow(t.DateOfExame);
objpres.className = t.Class.ClassName; // <- this works!
}
现在,这样做不会为您节省任何db查询-它只会稍微清理您的代码。由于延迟加载,当您请求查看时,EF仍然会从db 检索相关的Class
对象,而不是在顶部。但是,如果您在存储库中向EF查询添加Include
语句,您将开始保存—然后EF将在原始查询中包含相关项,并且它们将已经从db中获取。它看起来像下面这样:
var ctx = getYourEFContextSomehow(); // pseudocode, obviously...
var scheduleItems = ctx.Schedules.Include(s => s.Class);
// Add more Include for other objects
还有其他方法可以关闭特定属性或整个对象的延迟加载-查看http://msdn.microsoft.com/en-us/data/jj574232