我知道这可能是个愚蠢的问题,但是虽然......
我正在学习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决定的,如果我问的话,那就更好了。)
答案 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,但您最终可能会遇到用户之间的边缘情况竞争条件(缺乏更好的条款)。