繁体   English   中英

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

[英]ASP.NET MVC Pass Multiple Models to View From Controller

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

我有2个型号如下:

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个独立模型的信息的模型吗?

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

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所需的信息(要呈现给客户端的信息)

查看ViewModels

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

确保您的EmployeeSupervisor类不在您的Entity Framework内容中,此类严格用于显示与视图对应的数据。

回答你的问题

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

不,您正在寻找的是View Models。 Rachel Appel有一个很好的帖子,我强烈建议你阅读 - 使用ViewModels管理ASP.NET MVC应用程序中的数据和组织代码

什么是视图模型?

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

换句话说,它只是另一个简单的类,就像Employee和Supervisor,通常被称为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派上用场的地方。

最后,我还建议阅读Jimmy Bogard的这篇文章(我们如何做MVC - 查看模型)它对如何进行视图模型有一些非常好的观点,例如视图和视图模型的1:1映射等等。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM