使用ViewModel的CRUD操作

时间:2014-11-05 04:33:26

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

这将是一个很长的问题,但简而言之,我仍然无法弄清楚为什么在处理CRUD操作时使用View Model而不是Model更好

这是我到目前为止所学到的,请在整个过程中纠正我。因此,在尝试实施"创建"行动方法,它是"最佳实践"执行以下操作(我在这里首先使用实体​​框架代码):

DAL

  1. 您创建实体
  2. 您将这些实体映射到数据库
  3. 使用存储库模式
  4. 与DAL中的数据库进行交互
  5. 您创建界面
  6. BLL(控制器)

    1. 使用Unity / Ninject / Nhibernate等进行依赖注入以访问在DAL中创建的方法...
    2. 现在继续创建视图模型(可选)视图和控制器操作
    3. 例如,在创建控制器操作时,您可以执行以下操作:

      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
      

      究竟有什么区别?为什么要使用包含更多代码的View Model?

      我也尝试使用视图模型实现更新控制器操作:

      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?)。

      我在网上搜索并使用View Model看起来更像是一种更好的方法(强类型视图?),但是涉及的代码太多了,它假设发生了,或者我做错了。

1 个答案:

答案 0 :(得分:1)

是的,正确的方法是将您的实体映射到viewModel或DTO。

为什么这是一个很好的方法,因为如果你有一个包含20列的表,例如你的屏幕只使用了那20个列中的3列,那么你可以映射这3个用过的列并将它们发送到客户端,您希望从客户端返回相同的ViewModel / DTO,因此您只能在这种情况下围绕这3列构建验证。

如果您没有使用此appraoch,那么即使客户端屏幕没有使用/设置超过3列,您的客户端也需要发送20列(也许您会说我会设置服务器上那些未使用的列,可能会以意大利面条代码结束,以涵盖客户端使用该实体的所有情况。)

希望有所帮助。