EF dbcontext.进入ASP.网络应用程序
本文关键字:网络 应用程序 ASP 进入 dbcontext EF | 更新日期: 2023-09-27 18:18:04
我知道这可能是一个愚蠢的问题,但是尽管…
我正在学习ASP。我有一个关于dbcontext的问题。输入方法,让我们假设我们有这样的方法:
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"实例?如果这个movie parameter对象的所有属性都将被更改,那么如何确定该实例应该附加到哪一行呢?我得到了史密斯在我的头上,它将由Id决定,我们不能改变,但不确定,所以如果我问更好:)
当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
。
这是您不希望在用户之间共享db上下文的一个更大的原因,因为另一个用户试图更新相同的条目将导致第二个用户抛出异常。虽然事务将是ACID,但您最终可能会在用户之间出现边缘情况竞争条件(由于缺乏更好的术语)。
EF使用的每个表必须有一个主键,除非它是一个集合,这样EF知道主键所在的行保持不变。
这个方法有一个参数Movie
,但它与数据库无关。您必须更新从数据库中获取的对象,如:
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);
}
也许有更有效的方法,但我这样使用它,它工作得很好。
如果你的问题中的代码是一个版本,应该是一个工作版本,那么当我一直试图解决类似的问题时,它不适合我,所以我不得不通过使用上面的代码来解决它。