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 dbcontext.进入ASP.网络应用程序

当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);
}

也许有更有效的方法,但我这样使用它,它工作得很好。

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