2009-05-19 51 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