在创建代表多于1个实体的Controller时,如何构建支架?

时间:2012-07-31 21:24:49

标签: asp.net-mvc entity-framework

我有一个Entity Framework建模一个有大约30个表的遗留数据库。我正在使用ASP.NET MVC 4,并且很乐意在我的EDM中使用基于实体的脚手架。我已经看到了大量的例子,但我遇到了一个问题。我的需求并不像我所看到的那样,如下所示:创建一个支撑“客户”实体的控制器,在保存更改后,Controller操作接受客户作为其参数并使用模型绑定一切都很好完成以下操作后:

[HttpPost]
public ActionResult Create(Customer customer)
{
  if (ModelState.IsValid)
  {
     db.Customers.AddObject(customer);
     db.SaveChanges();
     return RedirectToAction("Index");  
   }
 }

完美而且非常正确;这对我不起作用。在我的情况下,我的屏幕需要来自大约6个不同实体的字段,并更新回相同的6个实体。

这是一个2部分问题:

  1. 当它不是一个简单的1实体到1个屏幕处理时,我怎么能将我的控制器和结果视图支架,如上面的简单示例?
  2. 我是否仍然可以使用模型绑定将更改持久保存回我的实体,因为生成的视图将再次由大约6个不同的实体组成,并且每个实体上没有大量的属性手动更新? / LI>

    如果我完全偏离基地,请指导我。我想知道我是如何完成这项任务的,因为它会在我的MVC应用程序中反复出现,我需要知道如何在可能的情况下仍然使用脚手架和模型绑定。

    谢谢!

1 个答案:

答案 0 :(得分:2)

当您遇到这样的场景时,是时候开始考虑使用ViewModels和EditModels,它们是专门用于显示View所需的确切属性的模型。

这样做的一个策略是:

  1. 在项目中创建新文件夹:ViewModels和EditModels。
  2. 对于每个详细信息视图,添加一个ViewModel类,并为每个编辑/创建视图添加一个EditModel类。
  3. 在您的控制器中,首次请求页面时,从实体映射到ViewModel / EditModel。在回发上,执行验证并从EditModel映射回您的实体。
  4. 一些注意事项:

    • 这确实增加了一些工作,但它确实是利用MVC的强类型视图功能的唯一可靠方法。
    • 为了最大限度地减少从实体到ViewModel的繁琐,您可以使用AutoMapper之类的东西在具有相同名称的属性之间自动映射(并为剩余的映射设置规则)。
    • 从EditModels返回实体可能需要一些手动工作。 AutoMapper可以处理某些场景,但它可能不是这种类型的映射的理想工具(从实体到ViewModel的效果要好得多)。我听说有人使用命令模式和规则引擎来执行映射回实体,但到目前为止,这些技术的真正详细解释或教程已经避开了我。

    ViewModel示例(来自NerdDinner教程)

    public class DinnerFormViewModel {
    
        // Properties
        public Dinner     Dinner    { get; private set; }
        public SelectList Countries { get; private set; }
    
        // Constructor
        public DinnerFormViewModel(Dinner dinner) {
            Dinner = dinner;
            Countries = new SelectList(PhoneValidator.AllCountries, dinner.Country);
        }
    }
    
    // controller actions
    
    [Authorize]
    public ActionResult Edit(int id) {
    
        Dinner dinner = dinnerRepository.GetDinner(id);
    
        return View(new DinnerFormViewModel(dinner));
    }
    
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(int id, FormCollection collection) {
    
        Dinner dinner = dinnerRepository.GetDinner(id);
    
        try {
            UpdateModel(dinner);
    
            dinnerRepository.Save();
    
            return RedirectToAction("Details", new { id=dinner.DinnerID });
        }
        catch {
            ModelState.AddModelErrors(dinner.GetRuleViolations());
    
            return View(new DinnerFormViewModel(dinner));
        }
    }
    

    来源:http://nerddinnerbook.s3.amazonaws.com/Part6.htm