简体   繁体   English

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

[英]EF dbcontext.Entry in ASP.NET app

I know it can be silly question, but although ... 我知道这可能是一个愚蠢的问题,但尽管...

Im learning ASP.NET MVC 4 and got one question about the dbcontext.Entry method, lets assume we got such method : 我正在学习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);
}

How the db.Entry(movie) determine which exactly row from the database is this "movie" instance? db.Entry(movie)如何确定该“ movie”实例到底是数据库中的哪一行? If all properties of this movie parameter object will be changed, how will it be possible to determine which row this instance should be attached to? 如果此电影参数对象的所有属性都将更改,那么如何确定该实例应附加到哪一行? I got smth on my head like it will determine by the Id which we cant change but not sure, so better if I ask :) 我有点疑惑,就像它将由我们无法更改但不确定的ID决定一样,如果我问的话会更好:)

This method has a parameter Movie , but it has nothing to do with database. 此方法具有参数Movie ,但与数据库无关。 You must update object that you will get from db like: 您必须更新将从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);
}

Maybe there is more efficient way , but I'm using it like this and it works fine. 也许有一种更有效的方法,但是我像这样使用它,并且效果很好。

If code in your question is a version that is supposed to be a working version, then it wasn't working for me when I have been trying to solve a similar problem so I had to solve it by using code above finally. 如果您问题中的代码是应该工作的版本,那么当我试图解决类似的问题时,它就对我不起作用,因此我不得不最终使用上面的代码来解决它。

EF使用的每个表都必须有一个主键,除非它是一个collection,所以EF知道由主键保持不变的行。

When EF generates the models it includes information on what column is the primary key in the database. EF生成模型时,它会包含有关数据库的主键所在列的信息。 db.Entry(model) binds the model to the context using that primary key and whatever primary key it shares in the database will be overwriten by the data in the model when SaveChanges() is called. db.Entry(model)使用该主键将模型绑定到上下文,并且调用SaveChanges()时,模型中的数据将覆盖数据库中共享的任何主键。 If the primary key is 0, or empty you must set the State to EntityState.Added instead of EntityState.Modified . 如果主键为0或为空,则必须将State设置为EntityState.Added而不是EntityState.Modified

As another answer said this can fail. 另一个回答是,这可能会失败。 The reason that binding can fail is that a context can only track a single distinct entity once (entity being a distinct class and id). 绑定失败的原因是,上下文只能跟踪单个不同的实体一次(实体是不同的类和ID)。 If you attempt to do the following you'll get an exception: 如果您尝试执行以下操作,则会出现异常:

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

Because the db context is already tracking a Movie with the same ID. 因为db上下文已经在跟踪具有相同ID的Movie

This is one of the larger reasons that you don't want to share db contexts between users, because another user attempting to update the same entry will cause the second one to throw an exception. 这是您不想在用户之间共享数据库上下文的更大原因之一,因为另一个试图更新同一条目的用户将导致第二个用户引发异常。 While the transaction will be ACID, you can end up with edge case race conditions (for lack of a better term) between users. 虽然交易将是ACID,但您最终可能会遇到用户之间的极端案例竞争情况(由于缺乏更好的期限)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM