【问题标题】:Can System.Web.MVC.UpdateModel update EF Navigation Properties?System.Web.MVC.UpdateModel 可以更新 EF 导航属性吗?
【发布时间】:2009-05-21 20:57:24
【问题描述】:

如果我的数据库中有 2 个表:FoobarFooFooId 标识,BarBarId 标识。一个 Bar 可以有 0 到多个 Foos 因此 Foo 有 BarId 作为外键。

我有一个代表这个的模型和一个可用于编辑 Foo 并选择(从下拉列表中)关联的 Bar 的视图。

给定控制器上的以下方法:

[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.

我的控制器从视图中的下拉列表中更新基于实体框架的模型的正确方法是什么?

【问题讨论】:

    标签: asp.net-mvc entity-framework


    【解决方案1】:

    不,默认模型绑定器无法执行此操作。您也很难编写自定义模型绑定器来执行此操作。 HTML SELECT 元素只会在描述中存储一个 ID 值,不足以实现大多数实体实例。所以我们只需要处理我们将仅获得一个 ID 的事实,这不足以在不访问数据库的情况下实现实体。

    因此,在更新实体的导航属性时,我们有两种选择:

    1. 从数据库中读取实体并将其分配给控制器中的导航属性。
    2. 不要尝试为导航属性具体化实体; instead just assign the EntityKey

    后者是我所做的。您可以在自定义模型绑定器或控制器中执行此操作。您可以在链接中阅读更多关于执行此操作的信息,并且我在该链接的 cmets 中有一些示例代码。

    即将发布的 .NET 4.0 中的新版本实体框架将具有一个名为“FK 关联”的新功能,这将大大简化此操作。

    【讨论】:

    • 带有 EFv4 的新版本 .NET (4.0) 确实在实体中引入了外键,但是,如果我们在视图中使用 EditorFor() 并为我们的类型使用强类型化的自定义模板导航属性的类型,然后默认模型绑定器成功地将导航属性的属性绑定到来自 EditorFor 模板的 POST 值。但是,这仍然不足以使上下文上的 SaveChanges() 起作用。它会出现以下错误:1)主键已经存在或 2)无法更改相关实体的主键(我们实际上并没有更改它)但仍然......
    • 并且默认绑定器会跳过外键属性,因此,我们可以选择手动设置此属性并将导航属性保留为空。然后它工作并保存更改。
    • 不可以将模型绑定器与附加对象结合使用吗?例如。如果下拉列表的名称为'Bar.Id',并且您让模型绑定器从表单中创建一个Foo 元素(称为myNewFoo),它会填写myNewFoo.Bar.Id。你不能打电话给db.BarTable.Attach(myNewFoo.Bar);吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 2012-05-05
    • 2018-04-03
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多