0

約 30 のテーブルを持つレガシー データベースをモデル化する Entity Framework があります。私は 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 つのエンティティに更新されます。

したがって、2部構成の質問:

  1. 上記の単純な例のように、1 つのエンティティから 1 つの画面への単純な取引ではない場合、コントローラーと結果のビューを足場にするにはどうすればよいですか?
  2. 結果のビューは約 6 つの異なるエンティティの結果であり、個々のエンティティのプロパティを手動で更新する必要はありません。

私が完全に基地から外れている場合は、私を元に戻してください。MVC アプリケーション全体で繰り返し発生するため、このタスクをどのように達成するかを正確に知りたいです。可能な場合は、スキャフォールディングとモデル バインディングを引き続き使用する方法を知る必要があります。

ありがとう!

4

1 に答える 1

3

このようなシナリオに遭遇した場合は、ViewModel と EditModel の使用を検討する時期です。これらは、View が必要とする正確なプロパティを表示するための専用モデルです。

これを行うための 1 つの戦略:

  1. プロジェクトに新しいフォルダーを作成します: ViewModels と EditModels。
  2. 詳細ビューごとに ViewModel クラスを追加し、編集/作成ビューごとに EditModel クラスを追加します。
  3. コントローラーで、ページが最初に要求されたときに、エンティティから ViewModel/EditModel にマップします。ポストバックで、検証を実行し、EditModel からエンティティにマップします。

いくつかのメモ:

  • これにより多少の作業が追加されますが、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

于 2012-07-31T21:27:49.237 に答える