[英]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和实体之间进行映射 ,例如Automapper或ValueInjecter
例如,如果您需要在视图中仅显示员工和主管的全名,您的视图模型可能如下所示:
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.