ASP.NET应用程序中的EF dbcontext.Entry

时间:2014-08-15 12:40:28

标签: c# asp.net asp.net-mvc entity-framework asp.net-mvc-4

我知道这可能是个愚蠢的问题,但是虽然......

我正在学习ASP.NET MVC 4并得到一个关于dbcontext.Entry方法的问题,我们假设我们有这样的方法:

public ActionResult Edit(Movie movie)
{
    if (ModelState.IsValid)
    {
        db.Entry(movie).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(movie);
}

db.Entry(movie)如何确定数据库中确切的行是这个" movie"实例?如果将更改此影片参数对象的所有属性,如何确定此实例应附加到哪一行?我觉得我的头像是由我们无法改变但不确定的Id决定的,如果我问的话,那就更好了。)

3 个答案:

答案 0 :(得分:0)

此方法具有参数Movie,但它与数据库无关。您必须更新将从db获得的对象,如:

public ActionResult Edit(Movie updatedMovie)
{
  if (ModelState.IsValid)
  {
   //db=your entities context
   //here you will get instance of record from db that you want to update
   Movie movie = db.Movie.Find(updatedMovie.Id);
   TryUpdateModel(movie);
   ctx.SaveChanges();
   return RedirectToAction("Index");
  }
  return View(movie);
}

也许有更有效的方式,但我正在使用它,它工作正常。

如果你的问题中的代码是一个应该是一个工作版本的版本,那么当我试图解决类似的问题时,它对我不起作用,所以我必须通过最终使用上面的代码来解决它。

答案 1 :(得分:0)

EF使用的每个表都必须有一个主键,除非它是一个集合,因此EF通过保持相同的主键知道该行。

答案 2 :(得分:0)

当EF生成模型时,它包含有关哪个列是数据库中主键的信息。 db.Entry(model)使用该主键将模型绑定到上下文,并且在调用SaveChanges()时,模型中共享的任何主键都将被模型中的数据覆盖。如果主键为0或为空,则必须将State设置为EntityState.Added而不是EntityState.Modified

另一个答案说这可能会失败。绑定失败的原因是上下文只能跟踪一个不同的实体(实体是一个不同的类和id)。如果您尝试执行以下操作,则会出现例外情况:

var dbModel = db.Movie.Find(movie.ID);
db.Entry(movie.ID) // Doesn't matter what you do, this will always fail 

因为db上下文已经在跟踪具有相同ID的Movie

这是您不希望在用户之间共享数据库上下文的一个较大原因,因为尝试更新同一条目的另一个用户将导致第二个用户抛出异常。虽然交易将是ACID,但您最终可能会遇到用户之间的边缘情况竞争条件(缺乏更好的条款)。