ASP.NET MVC传递多个模型从控制器查看

时间:2015-04-22 18:35:09

标签: c# asp.net-mvc entity-framework

我需要有一个显示Employee First和Last Name以及Employees关联的Supervisor First和Last名称的视图。

我有两个模型如下:

public class Employee
{
    public int EmployeeID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Department { get; set; }
    public int SupervisorID { get; set; }

    public virtual ICollection<Supervisor> Supervisor { get; set; }
}

public class Supervisor
{
    public int SupervisorID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Phone { get; set; }
    public string Email { get; set; }
    public string Department { get; set; }

    public virtual Employee Employee { get; set; }
}

要显示所需的数据,我创建了另一个模型:

public class EmployeeSupervisor
{
    public int EmployeeID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Department { get; set; }

    public string SupFirstName { get; set; }
    public string SupLastName { get; set; }
    public string SupPhone { get; set; }
    public string SuoEmail { get; set; }
    public string SupDepartment { get; set; }
}

在控制器的详细操作中,我执行以下操作:

Employee employee = db.Employees.Find(id);
Supervisor supervisor = db.Supervisors.Find(employee.SupervisorID);

EmployeeSupervisor es = new EmployeeSupervisor
{
    EmployeeID = employee.EmployeeID,
    Department = employee.Department,
    FirstName = employee.FirstName,
    LastName = employee.LastName,
    SupFirstName = supervisor.FirstName,
    SupLastName = supervisor.LastName,
    SuoEmail = supervisor.Email,
    SupPhone = supervisor.Phone,
    SupDepartment = supervisor.Department
};

return View(es);

然后在视图中我有

@model TimeOffV3.Models.EmployeeSupervisor

然后我在视图中执行以下操作

@Html.DisplayFor(model => model.FirstName)
@Html.DisplayFor(model => model.LastName)
@Html.DisplayFor(model => model.SupFirstName)
@Html.DisplayFor(model => model.SupLastName)

当我使用EmployeeSupervisor模型类完成上述任务时,实体框架为数据库中的EmployeeSupervisor创建了一个相应的表(如预期的那样)。这让我相信我的做法是错误的,因为我无法想象每次我想要显示来自2个不同模型的数据,我需要创建一个新的相应模型和表格。

我这样做的方式是正确的吗?我是否应该能够使用Employee类中定义的导航属性访问超级用户信息?我可以传递多个模型,因此我不必创建包含2个不同模型的信息的模型吗?

4 个答案:

答案 0 :(得分:3)

实际上,视图只接收一个模型,但此模型不必是平坦的。您的视图模型可以包含每个实体的单独属性

public class EmployeeSupervisor
{
    public Employee Employee { get; set; }
    public Supervisor Supervisor{ get; set; }
}

在您看来,您可以按照以下方式使用它们:

   @Html.DisplayFor(model => model.Employee.FirstName)
   @Html.DisplayFor(model => model.Employee.LastName)
   @Html.DisplayFor(model => model.Supervisor.FirstName)
   @Html.DisplayFor(model => model.Supervisor.LastName)

您应该知道的另一件事是,Views不必使用实体(在数据库中具有相应表的那些实体)。您可以创建仅包含视图中使用的属性的ViewModel。有些库可以帮助您在ViewModel和实体之间进行映射,例如AutomapperValueInjecter

例如,如果您需要在视图中仅显示员工和主管的全名,您的视图模型可能如下所示:

public class EmployeeSupervisorViewModel
{
    public string EmployeeName { get; set; }
    public string SupervisorName { get; set; }
}

控制器:

    Employee employee = db.Employees.Find(id);
    Supervisor supervisor = db.Supervisors.Find(employee.SupervisorID);

    var model = new EmployeeSupervisorViewModel
    {
        EmployeeName =  string.Format("{0} {1}",employee.FirstName, employee.LastName),
        SupervisorName =  string.Format("{0} {1}",supervisor.FirstName, supervisor.LastName),
    };

    return View(model);

EmployeeSupervisorViewModel不是实体,不应该有数据库表它仅在视图/控制器级别使用,并且仅包含View所需的信息(要呈现给客户端的信息)< / p>

答案 1 :(得分:2)

查看ViewModels

您有正确的想法,但问题是您不应该使用该视图模型创建另一个表。

确保您的EmployeeSupervisor课程不在您的实体框架内,此类严格用于显示与视图对应的数据。

答案 2 :(得分:1)

回答你的问题

  

我完成这个的方式是正确的吗?

不,你要找的是View Models。 Rachel Appel有一篇很好的帖子,我强烈建议你阅读 - Use ViewModels to manage data & organize code in ASP.NET MVC applications

什么是视图模型?

  

ViewModels允许您从一个或多个数据模型(在您的情况下,这将是Employee和Supervisor)中形成多个实体,或者将源作为单个对象,针对视图的消费和呈现进行优化。 - Rachel Appel

换句话说,它只是另一个简单的类,就像雇员和主管通常被称为POCO

public class EmployeeSupervisorViewModel
{
    public int EmployeeId { get; set; }
    public string Department { get; set; }
    public string FristName { get; set; }
    public string LastName { get; set; }
    public string SupFirstName { get; set; }
    public string SupLastName { get; set; }
    public string SupEmail { get; set; }
    public string SupPhone { get; set; }
}

这使您可以在Controller

中执行以下操作
        var employee = _db.Employee.Find(id);
        var supervisor = _db.Supervisor.Find(employee.SupervisorID);

        var model = new EmployeeSupervisorViewModel()
        {
            EmployeeId = employee.EmployeeId,
            Department = employee.Department,
            FristName = employee.FirstName,
            LastName = employee.LastName,
            SupFirstName = supervisor.FirstName,
            SupLastName = supervisor.LastName,
            SupEmail = supervisor.Email,
            SupPhone = supervisor.Phone
        };
        return View(model);

在您的视图中,只需接受View Model,EmployeeSupervisorViewModel作为模型,并像以前一样对其进行操作。

@model TimeOffV3.Models.EmployeeSupervisorViewModel

从长远来看,对于较大的View Models,这种映射可能有点单调乏味。这是AutoMapper派上用场的地方。

最后我还建议阅读此post from Jimmy Bogard (How we do MVC – View models)它有一些关于如何进行视图模型的非常好的观点,例如视图和视图模型的1:1映射等。

答案 3 :(得分:0)

创建一个视图模型类,它将employee和supervisor对象包装为属性。在EF模型之外执行此操作。

将实例传递给您的视图,通过EF填充属性并访问属性以获取值。