0

我有实体框架对具有大约 30 个表的旧数据库进行建模。我正在使用 ASP.NET MVC 4,并且希望在我的 EDM 中使用基于实体的脚手架。我已经看到了很多这方面的例子,但我遇到了一个问题。我的需求不像我所看到的示例那样千篇一律:创建一个支撑“客户”实体的控制器,并在保存更改后,控制器操作将客户作为其参数并使用模型绑定一切都很好完成以下操作后:

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

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

所以一个两部分的问题:

  1. 当它不是像上面的简单示例那样简单的 1 实体到 1 屏幕交易时,我什至如何搭建我的控制器和结果视图?
  2. 我是否仍然能够使用模型绑定将更改持久化回我的实体,因为生成的视图将再次是大约 6 个不同实体的结果,并且无需对每个单独实体的属性进行大量手动更新?

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

谢谢!

4

1 回答 1

3

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

这样做的一种策略:

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

几点注意事项:

  • 这确实增加了一些工作,但它确实是利用 MVC 的强类型视图功能的唯一可靠方法。
  • 为了最大程度地减少从实体到 ViewModel 的乏味,您可以使用AutoMapper之类的工具在具有相同名称的属性之间自动映射(并为剩余的映射设置规则)。
  • 从 EditModel 回到实体可能需要一些手动工作。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

于 2012-07-31T21:27:49.237 回答