如何使用EF更新控制器中的对象?

时间:2011-02-27 23:45:17

标签: entity-framework asp.net-mvc-3 repository

我在谷歌上搜索过,但似乎太明显了,没有人在谈论这个。

我有一个我的表的存储库,我希望能够更新我的数据库。

在Linq2Sql上你有类似的东西:

public void SaveCar(Car car)
{
    if (carTable.GetOriginalEntityState(car) == null)
    {
        carTable.Attach(product);
        carTable.Context.Refresh(RefreshMode.KeepCurrentValues, car);
    }
    carTable.ContextSubmitChanges();
}

并且在控制器中,只需在POST Edit方法上调用此方法。

我如何在EF中做这样的事情?更好的方式。

我看到使用TryUpdateModel(模型)的代码,但我不确定是否更新了我在数据库上的内容,或者我必须首先选择对象并使用FormCollection更新它...

我很困惑,我只需要从表单中获取一辆汽车并使用相同的ID从数据库更新汽车。那么,我必须在控制器和存储库中做些什么呢?

谢谢。

编辑:如果我不清楚,我真的不知道我放在那里是否需要转换到EF。我只是想知道如何使用EF更新对象的实例(EFCodeFirst是我正在使用的)。我如何从表单接收实例并在数据库中更新它。

2 个答案:

答案 0 :(得分:2)

TryUpdateModel方法可用于为对象分配值,使用其属性名称与Web请求中指定的值之间的映射。话虽这么说,你可以通过这样做来实现相同的行为:

[HttpPost]
public ActionResult Edit(int id, FormCollection form)
{
    Car entity = new Car { Id = id };

    // This will attach the car entity to the content in the unchanged state.
    this.EntityFrameworkObjectContext.Cars.Attach(car);

    TryUpdateModel(entity, form.ValueProvider.ToXYZ()); // Can't remember the exact method signature right now

    this.EntityFrameworkObjectContext.SaveChanges();
    ...
}

当将实体附加到上下文时,您基本上只是通知上下文您有一个实体,他应该注意这个实体。一旦附加了实体,上下文将跟踪对其所做的更改。

但是此方法仅适用于标量属性,因为导航属性不会使用此方法更新。如果启用了外键属性(如分配给类别的产品也具有链接两者的CategoryId属性),您仍应该能够使用此方法(因为导航属性使用标量属性进行映射)。

编辑:另一种方法是接受Car实例作为参数:

[HttpPost]
public ActionResult Edit(int id, Car car)
{
    Car entity = new Car { Id = id };

    // This will attach the car entity to the content in the unchanged state.
    this.EntityFrameworkObjectContext.Cars.Attach(entity);

    // It is important that the Car instance provided in the car parameter has the
    // the correct ID set. Since the ApplyCurrentValues will look for any Car in the
    // context that has the specified primary key of the entity supplied to the ApplyCurrentValues
    // method and apply it's values to those entity instance with the same ID (this
    // includes the previously attached entity).
    this.EntityFrameworkObjectContext.Cars.ApplyCurrentValues(car); 
    this.EntityFrameworkObjectContext.SaveChanges();
    ...
}

您还可以滚动自己的ModelBinder,它实际上具有对您的Entity Framework Context的引用,并查看是否在表单/查询中指定了Car.Id。如果存在ID,您可以直接从上下文中获取要更新的实体。此方法需要一些努力,因为您必须首先确保搜索ID,然后应用所有指定的属性值。如果你有兴趣,我可以给你一些考试。

答案 1 :(得分:2)

一个月,没有答案,是自动回复的时间。

我的问题的答案是:

在控制器中是这样的:

if (ModelState.IsValid)
    repo.SaveCar(car);

并在回购中:

context.Entry(Car).State = EntityState.Modified;

就是这样,这就是保存对象的方法。