2009-05-19 2 views
4

データベースに2つのテーブルがある場合:Fooおよびバーです。 フーFooIdバーによって識別されBarIdによって識別子です。 バーは、0〜多くのFoosを持つことができます。したがって、Fooは外部キーとしてBarIdを持っています。System.Web.MVC.UpdateModelはEFナビゲーションプロパティを更新できますか?

は、私はこれを表すモデルと、(ドロップダウンから)フーを編集し、選択するために使用することができるビュー関連バーを有します。私のコントローラのための正しい方法は何

The model of type 'TestApplication.Models.Foo' was not successfully updated. 

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(int id, FormCollection formCollection) 
{ 
    Foo originalFoo = FooById(id); 

    if (!ModelState.IsValid) 
    { 
     return View(new VenueViewModel(originalVenue, _db.GetCounties(), _db.VenueTypeSet)); 
    } 

    UpdateModel(originalFoo); 

    /* Instead of using UpdateModel I could just iterate through 
     formCollection and manually update originalFoo, it would 
     work but surely there is a better way? */ 

    _db.SaveChanges(); 

    return RedirectToAction("Index"); 
} 

への呼び出しのUpdateModelはありませんのInnerExceptionInvalidOperationExceptionがをスロー:コントローラ上で次の方法を考える

私のビューでドロップダウンからEntity Frameworkベースのモデルを更新するには?

答えて

7

いいえ、デフォルトのモデルバインダーはこれを実行できません。それを行うためにカスタムモデルのバインダーを書くのは難しいでしょう。 HTML SELECT要素はID値を記述に格納するだけで、ほとんどのエンティティインスタンスを実現するには十分ではありません。だから、私たちはIDだけを取得するという事実と関係があります。これは、データベースにぶつかることなくエンティティを実現するには十分ではありません。データベースからのエンティティに

  1. 読むと、コントローラのナビゲーションプロパティに割り当て:エンティティのナビゲーションプロパティを更新する際に

    したがって、我々は2つの選択肢があります。

  2. ナビゲーションプロパティのエンティティをマテリアライズしようとしないでください。 instead just assign the EntityKey

後者は私がしていることです。カスタムモデルバインダーやコントローラーで行うことができます。リンクでこれを行うことについてもっと多くのことを読むことができます。そのリンクのコメントにサンプルコードがあります。

今後の.NET 4.0のEntity Frameworkの新しいバージョンには、これをかなり容易にする「FK Associations」という新しい機能が追加されます。

+0

EFv4を使用した.NET(4.0)の新しいバージョンでは、実際にエンティティに外部キーが導入されていますが、EditorFor()をビューで使用すると、ナビゲーションプロパティの型デフォルトのモデルバインダーは、ナビゲーションプロパティのプロパティをEditorForテンプレートのPOSTed値に正常にバインドします。しかし、これは、コンテキスト上のSaveChanges()が機能するにはまだ十分ではありません。 1)プライマリキーが既に存在するか、2)関連エンティティのプライマリキーを変更できませんが(実際には変更されていません)、まだ – mare

+0

です。デフォルトのバインダは外部キーのプロパティをスキップします。左には、このプロパティを手動で設定し、ナビゲーションプロパティをnullのままにするオプションがあります。次に、変更を保存して保存します。 – mare

+0

モデルバインダーをオブジェクトの取り付けに併用することはできませんか?例えば。ドロップダウンリストの名前が '' Bar.Id ''で、モデルバインダーにフォームからFoo要素( 'myNewFoo'という名前)を作成させると、それは' myNewFoo.Bar.Id'になります。 'db.BarTable.Attach(myNewFoo.Bar);を呼び出すことができませんでしたか? – Flater

関連する問題