在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个项目:

  1. DomainClass
  2. <
  3. 库/gh>MVC项目

  1. 这是一个好方法,我转换这些Id到他们的名字在MVC层,或者是更好地使一个存储库或创建一个模型的时间表列表?

  2. 在最后一行,当我想返回我的列表时,我得到了这个错误:

    传入字典的模型项的类型是'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>

在MVC中返回一个列表会导致错误

您的视图可能有一个像这样的强类型模型

@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