2009-05-19 52 views
4

如果我在我的數據庫中有兩張桌子:Foo酒吧FooFooId標識,標識爲BarId。 A Bar可以有0到多個Foos因此Foo有BarId作爲外鍵。System.Web.MVC.UpdateModel是否可以更新EF導航屬性?

我有表示該模型,並可以被用於編輯和選擇(從下拉)的視圖相關聯的酒吧

考慮到控制器上的以下方法:

[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引發InvalidOperationException異常沒有的InnerException

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

什麼是我的控制器的正確方法在我看來從下拉菜單中更新基於實體框架的模型?

回答

7

不,默認的模型聯編程序不能執行此操作。你也很難寫一個自定義的模型綁定來做到這一點。 HTML SELECT元素只會在描述中存儲一個ID值,不足以實現大多數實體實例。所以我們只需要處理一個事實,即我們只會得到一個ID,這不足以實現沒有敲入數據庫的實體。

因此,更新實體的導航屬性的時候,我們有兩個選擇:

  1. 閱讀從數據庫實體並將其分配給在控制器中的導航屬性。
  2. 不要試圖實現導航屬性的實體; instead just assign the EntityKey

後者就是我所做的。您可以在自定義模型聯編程序或控制器中執行此操作。你可以閱讀更多,關於在鏈接上做這件事,我在鏈接的評論中有一些示例代碼。

即將推出的.NET 4.0中新版本的實體框架將會有一個名爲「FK關聯」的新功能,這將使得這個功能變得相當容易。

+0

帶有EFv4的.NET(4.0)的新版本確實將外鍵引入到實體中,但是如果我們在視圖中使用EditorFor()併爲我們的類型強制鍵入導航屬性類型那麼默認模型聯編程序會成功將導航屬性的屬性綁定到EditorFor模板的POSTed值。但是,這對於上下文中的SaveChanges()仍然不夠用。它與任何錯誤1)主鍵已經存在或2)不能改變相關實體的主鍵(我們實際上並沒有改變它),但仍然.. – mare 2011-01-29 17:21:51