C# 使用ViewModel执行CRUD操作

C# 使用ViewModel执行CRUD操作,c#,asp.net-mvc,entity-framework,viewmodel,C#,Asp.net Mvc,Entity Framework,Viewmodel,这将是一个很长的问题,但简而言之,我仍然无法理解为什么在处理CRUD操作时使用视图模型而不是模型更好 这是我到目前为止所学的,请一路上纠正我。因此,在尝试实现“创建”操作方法时,执行以下操作是“最佳实践”(我在这里首先使用实体框架代码): 达尔 您可以创建您的实体 将这些实体映射到数据库 您可以使用存储库模式与DAL中的数据库进行交互 您可以创建您的界面 BLL(控制器) 您使用Unity/Ninject/Nhibernate等进行依赖项注入以访问在DAL中创建的方法 现在继续创建视图模型(可选

这将是一个很长的问题,但简而言之,我仍然无法理解为什么在处理CRUD操作时使用视图模型而不是模型更好

这是我到目前为止所学的,请一路上纠正我。因此,在尝试实现“创建”操作方法时,执行以下操作是“最佳实践”(我在这里首先使用实体框架代码):

达尔

  • 您可以创建您的实体
  • 将这些实体映射到数据库
  • 您可以使用存储库模式与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
    
    或:

    鉴于此,请执行以下操作:

    @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,那么您的客户机需要发送20列集,即使客户机屏幕没有使用/设置超过3列(也许您会说,我将在服务器上设置这些未使用的列,这可能会以一个意大利面代码结束,以涵盖您的客户机使用该实体的所有情况)


    希望这会有所帮助。

    该模型只是您实体的一种表示。它不必处理任何业务逻辑,因此是BLL。换句话说,这个模型是“愚蠢的”。与逻辑相关的一切都应由ViewModel处理。(非常简单的答案,但您应该阅读MVVM/MVC体系结构)许多很好的答案解释了使用视图模型@Tico的好处是的,我知道模型只是我的实体,但为什么它不应该处理业务逻辑?人们只是说你不应该,但为什么呢?@EricWang,通过使用层(DAL,BLL),你的代码将很容易重用。并不是说你不能用。但这会破坏建筑的目的。处理未来的变化不太容易出错。刚开始的时候我也有同样的感觉,但当事情开始发展时,我明白了每一层的目的。想要实现新的逻辑吗?使用BLL,DAL将保持完整,反之亦然。您可以通过两种方式使用automapper使其更简单。是的,这是一点额外的代码(通常你可以剪切和粘贴属性,然后添加验证属性,
    SelectList
    properties等等),但我发现它的好处大于额外的几分钟编码。
    [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);  
    }