这将是一个很长的问题,但简而言之,我仍然不明白为什么在处理CRUD操作时使用视图模型而不是模型更好
这是我到目前为止学到的,请一路上纠正我。因此,当尝试实现"创建"操作方法时,"最佳实践"是执行以下操作(我首先使用实体框架代码):
DAL-
- 创建实体
- 将这些实体映射到数据库
- 使用存储库模式与DAL中的数据库进行交互
- 您创建界面
BLL(控制器)
- 您使用Unity/Ninject/Nhibernate等进行依赖注入以访问在DAL中创建的方法
- 现在继续创建视图模型(可选)视图和控制器操作
例如,当创建控制器操作时,您可以这样做:
public ActionResult Create()
{
return View();
}
//
// POST: /CRUD/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Employee employee) ---- Using actual entities
{
if (ModelState.IsValid)
{
repository.Add(employee);
return RedirectToAction("Index");
}
return View(employee);
}
在视图中你做:
@model foo.Entities.Employee
或者:
public ActionResult Create()
{
var model = new EmployeeViewModel();
return View(model);
}
//
// POST: /CRUD/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(EmployeeViewModel model) ---- Using viewmodel
{
if (ModelState.IsValid)
{
//map here or use automapper
var employee = new Employee()
employee.Name = model.Name;
repository.Add(employee);
return RedirectToAction("Index");
}
return View(employee);
}
鉴于你这样做:
@model foo.Model.EmployeeViewModel
到底有什么区别?为什么要使用包含更多代码的视图模型??
此外,我还试图使用视图模型来实现更新控制器操作:
public ActionResult Edit(int jobId)
{
Job job = repository.FindJob(jobId);
if (job == null)
{
return HttpNotFound();
}
var model = new JobEditViewModel();
//mapping to get information from database and display
ConfigureEditViewModel(job, model);
return View(model);
}
private void ConfigureCreateViewModel(JobCreateViewModel model)
{
model.Title = job.Title;
model.NumberOfPosition = job.NumberOfPosition;
model.Salary = job.Salary;
model.SelectedSalaryPeriodId = job.SalaryPeriodId;
model.PostCode = job.PostCode;
model.SelectedLocationId = job.LocationId;
model.IndustryExperiencePeriod = job.IndustryExperiencePeriod;
model.Role = job.Role;
model.Description = job.Description;
model.SelectedEmploymentHourId = job.EmploymentHourId;
model.SelectedDurationId = job.DurationId;
model.SelectedShiftId = job.ShiftId;
model.SelectedWorkDayId = job.WorkDayId;
}
以及在张贴时
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(JobEditViewModel model) ---- Using viewmodel
{
if (ModelState.IsValid)
{
//mapping model back to the entity...
var job = new Job()
job.Title = model.Title;
job.NumberOfPositions = .......
repository.Edit(job);
return RedirectToAction("Index");
}
return View(job);
}
使用视图模型时,将实体映射到模型以显示信息,然后在更新时将模型映射回实体(操作后)。我认为我在映射过程中遗漏了一些东西,对我来说,我似乎一直在视图模型和实际实体之间来回映射,我是不是遗漏了一些事情(这就是使用automapper的原因吗?)。
我在网上搜索过,使用视图模型似乎是更好的方法(强类型视图?),但其中涉及的代码太多了,这是假设发生的,还是我做错了。
是的,正确的方法是将实体映射到viewModel或DTO中。
为什么这是一个很好的方法,因为如果你有一个有20列的表,而你的屏幕只使用了这20列中的3列,那么你可以映射这3个使用过的列并将它们发送到客户端,你希望客户端返回相同的ViewModel/DTO,所以只有在这种情况下,你才能围绕这3列构建验证。
如果你没有使用这个appraoch,那么即使客户端屏幕没有使用/设置超过3列,你的客户端也需要发送20列集(也许你会说我会在服务器上设置那些未使用的列,这可能会以一个意大利面条代码结束,以涵盖你的客户端使用该实体的所有情况)。
希望能有所帮助。