我需要有一个显示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个不同模型的信息的模型吗?
答案 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和实体之间进行映射,例如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所需的信息(要呈现给客户端的信息)< / p>
答案 1 :(得分:2)
答案 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填充属性并访问属性以获取值。