【问题标题】:ASP.NET MVC 5 Get inherited class data in ViewASP.NET MVC 5 在视图中获取继承的类数据
【发布时间】:2016-04-29 22:08:38
【问题描述】:

我正在学习 asp.net MVC,我正在尝试构建一个应用程序,但我的视图中无法显示数据。我在这里搜索,但无法找到此问题的答案。 我有一个模型结构,其中 Person 是我的基类和从 Person 继承的另外两个类 - 教授和学生。 我想要的是当我在我的应用程序中单击学生选项卡时,它只显示学生数据,当我单击教授时,它只显示教授数据以及他们的公共数据和每种类型的特定数据。现在我只有一张带有学生和教授属性的“人”表。 提前致谢!!

这是我的基类 Person 和子类 Professor 和 Student

public abstract class Person
{
    public virtual int PersonID { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string Email { get; set; }
    public virtual string Login { get; set; }
    public virtual string Senha { get; set; }
    public virtual string Address { get; set; } 
}
public class Professor : Person
{
    public string CREF { get; set; }
    public string Education { get; set; }
    public virtual ICollection<Session> Sessions { get; set; }
} 
public class Student : Person
{
    public DateTime SessionStart { get; set; }
    public DateTime SessionEnd { get; set; }
    public virtual ICollection<TSession> Sessions { get; set; }
}

这是我的 StudentController

public class StudentController : Controller
{
    private SessionContext db = new SessionContext();

    public ActionResult Index()
    {
        return View(db.People.ToList());
    }
}

这是我的索引学生视图

....

<table class="table">
    <tr>
        <th>@Html.DisplayNameFor(model => model.FirstName)</th>
        <th>@Html.DisplayNameFor(model => model.LastName)</th>
         ....
    </tr>
    @foreach (var item in Model) {
        <tr>
            <td>@Html.DisplayFor(modelItem => item.FirstName)</td>
            <td>@Html.DisplayFor(modelItem => item.LastName)</td>
            ....
        </tr>
    }
</table>

【问题讨论】:

  • 如果你有一个表,那么你需要一个属性来识别一个人是Professor还是Student,你可以根据该属性过滤结果
  • 另请参考How to create a Minimal, Complete, and Verifiable example - 99% 的代码与问题无关。
  • 您发布了AccountController,而不是StudentController。那是一堆我认为不相关的身份验证代码。
  • 我认为您粘贴的是 AccountController 而不是 StudentController。
  • 对不起,我没有注意到。

标签: c# asp.net asp.net-mvc asp.net-mvc-5


【解决方案1】:

我已将原始答案保存在 gist 中,因为它并没有真正回答 OP 的问题。具有讽刺意味的是,我使用的源旨在解决相反的问题,即需要将两个表合并到一个页面中。

这里 OP 说有一个数据库表 Persons,我们想从中推断出两个视图,ProfessorStudent,并将它们显示在不同的页面上。

这样——

//StudentController.cs
public class StudentController : Controller
{
    private SessionContext db = new SessionContext();

    public ActionResult Index()
    {
        var result = db.People.Where(x => !string.IsNullOrEmpty(x.Education));
        return View(result.ToList());
    }
}

还有……

//ProfessorController.cs
//...
    var result = db.People.Where(x => string.IsNullOrEmpty(x.Education));
//...

...可能是分离视图的一种方式。

但是,正如 cmets 中所建议的,如果您的设计需要在应用程序中单独显示和处理这些对象,您可能只想拥有多个表。 TSQL 中的一个示例:

CREATE TABLE dbo.Person (
    Id int NOT NULL PRIMARY KEY,
    Name nvarchar(200) NOT NULL --unicode
);
CREATE TABLE dbo.Professor (
    Id int NOT NULL PRIMARY KEY,
    Education nvarchar(50) NOT NULL,
    PersonId int FOREIGN KEY REFERENCES Person.Id
);
--etc

但由于我不是 DBA,而且您使用的是 ASP.NET,因此您可以使用 Entity Framework 的 Code First 表生成,我认为这就是您在上面暗示的内容:

public class Person
{
    public int PersonId { get; set; }
    [Required] // == NOT NULL
    public string Name { get; set; }
    // demais... (the rest)
}

public class Professor // no inheritance!
{
    public int ProfessorId { get; set; }
    [Required]
    public string Education { get; set; }
    [ForeignKey("PersonId")]
    public Person Person { get; set; }
}

请注意,这是一对一的关系,老实说,我还没有对此进行验证。 Julie Lerman 在 Microsoft 的数据开发人员中心网站上有很多帖子,例如涉及这些关系的 this one。 (这是我最好的快速谷歌搜索(tm)并指向 Entity Framework 4.1,所以我相信你可以找到更新的东西。但原则应该仍然有效。)

哇!

【讨论】:

  • 我认为这并不能真正解决 OP 的问题 - 即过滤结果,以便一个选项卡显示 Professor 的集合,另一个选项卡显示 Student 的集合 - 例如- var students = db.Pessoas.Where(x =&gt; x.SomeProperty == someValue);var professors = db.Pessoas.Where(x =&gt; x.SomeProperty == anotherValue);
  • 啊。我以为他宁愿把那部分写下来,我想我认为他发布的代码会放在 EditorTemplate 中,就像这样...github.com/chaim1221/Machete/blob/master/Machete.Web/Views/…
  • 换句话说,如果他使用这个模板模式,他可以为教授、学生等创建单独的视图和控制器,这些视图和控制器由不同的选项卡激活。
  • 您所显示的问题是模板中的模型是@model MyApp.Person,这意味着它只能显示基本属性。如果解决方案涉及使用 EditorTemplate,则需要 2 个(Professor 一个,Student 一个)
  • 这是有道理的。对于此示例,使用 DisplayTemplate 可能也更好。我会进行修改。
【解决方案2】:

这个问题有两部分,即在视图上显示数据和通过Entity Framework等方法从数据库中获取数据。因为这是一个ASP.NET MVC 的问题,所以我只会回答视图上数据的显示。如何取回数据取决于您。

我个人会为此在数据库中有两张表,一张给学生,一张给教授。这值得商榷,但我会这样做。

您的 professorstudent 课程在我看来是正确的。

您需要为此创建一个视图模型。视图模型包含您传递给视图的数据。我对什么是视图模型给出了详细的回答。请阅读:

What is ViewModel in MVC?

首先创建您将发送到视图的视图模型。您可能会在屏幕上显示其他数据,但我只会显示学生列表和教授列表。所以对于每一个你都会有一个属性来包含数据:

public class ViewModel
{
     public List<Student> Students { get; set; }

     public List<Professor> Professors { get; set; }
}

在您的 Index 操作方法中,您将创建此视图模型的实例,用学生和教授数据填充它,然后将其发送到视图:

public ActionResult Index()
{
     // Please make use of a repository to handle this
     // You need to set up your data layer to handle students and professors
     SessionContext db = new SessionContext();

     ViewModel model = new ViewModel();

     // Get all the students
     model.Students = db.Students.ToList();
     // Get all the professors
     model.Professors = db.Professors.ToList()

     return View(model);
}

现在您的视图模型中填充了学生和教授数据。您将它发送到视图,视图将显示它。您将需要 2 个HTML 表,并在需要时让您的选项卡显示正确的表:

@model Project.Models.ViewModel

<table>
     @foreach (var student in Model.Students)
     {
          <tr>
               <td>@student.FirstName</td>
               <td>@student.FirstName</td>
          </tr>
     }
</table>

<table>
     @foreach (var professor in Model.Professors)
     {
          <tr>
               <td>@professor.FirstName</td>
               <td>@professor.FirstName</td>
          </tr>
     }
</table>

这是一种简单的方法,可能不是您想要的,但它会引导您走上正确的道路,并为您提供可以做什么的想法。

【讨论】:

    【解决方案3】:

    感谢所有花时间帮助我解决这个问题的人,我能够从继承的类中提取特定属性并在不同的视图中显示它,所以我决定创建两个表 Student 和 Professor 并解决了我的问题。

    【讨论】:

      猜你喜欢
      • 2011-01-22
      • 1970-01-01
      • 2012-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-27
      • 1970-01-01
      相关资源
      最近更新 更多