我正在阅读以下有关实体框架6 Link的教程。在名为“为教师添加编辑页面”的部分中,作者在Post编辑操作方法内编写了以下代码:-

[HttpPost, ActionName("Edit")]
[ValidateAntiForgeryToken]
public ActionResult EditPost(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    var instructorToUpdate = db.Instructors
       .Include(i => i.OfficeAssignment)
       .Where(i => i.ID == id)
       .Single();

    if (TryUpdateModel(instructorToUpdate, "",
       new string[] { "LastName", "FirstMidName", "HireDate", "OfficeAssignment" }))
    {
       try
       {
          if (String.IsNullOrWhiteSpace(instructorToUpdate.OfficeAssignment.Location))
          {
             instructorToUpdate.OfficeAssignment = null;
          }

          db.Entry(instructorToUpdate).State = EntityState.Modified;
          db.SaveChanges();

          return RedirectToAction("Index");
       }
       catch (RetryLimitExceededException /* dex */)
      {
         //Log the error (uncomment dex variable name and add a line here to write a log.
         ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
      }
   }
   return View(instructorToUpdate);
}


该代码将涵盖以下三个条件:


如果用户清除了办公室分配并且它最初具有值,则必须删除和删除OfficeAssignment实体。
如果用户输入办公室分配值,并且该值最初为空,则必须创建一个新的OfficeAssignment实体。
如果用户更改了办公室分配的值,则必须在现有OfficeAssignment实体中更改该值。


那么这是否意味着

db.Entry(instructorToUpdate).State = EntityState.Modified;


如果讲师没有预先使用OfficeAssignment对象,将导致对OfficeAssignment记录执行插入语句吗?统治这个的规则是什么?

这是完整的模型图:

最佳答案

DbContext.Entry方法用于进行显式加载,这意味着它使您可以访问DbContext具有的有关实体的所有信息。这超出了存储在实际实体属性中的值,并且包括诸如实体状态和从数据库中检索每个属性时的原始值之类的内容。

调用TryUpdateModel方法时,它将使用模型绑定程序中的值更新属性(将其名称作为参数传递)。这些属性之一是OfficeAssignment,也将更新。如果您认为没有输入Location,那么就没有理由创建新的OfficeAssigment(那样就需要执行instructorToUpdate.OfficeAssignment = null;,因为即使您没有输入新的Location >,您将拥有OfficeAssignment的实例)。如果添加新的Location,则将创建一个新的OfficeAssignment,如果修改了Location,则将修改其值。
执行此操作时:

db.Entry(instructorToUpdate).State = EntityState.Modified;


您将在实体上设置一个标志,指示其已更改。调用SaveChanges方法时,Modified标志使实体框架创建SQL语句来更新数据库行。数据库行的所有列都将更新,包括用户未更改的列,并发冲突将被忽略。为了更好地了解发生了什么,您可以将Instructor实例看起来像一棵树。 Code First认识到您具有导航属性,因此需要更新或插入(取决于大小写)。如果OfficeAssignmentIddefault(int)不同(我想说是整数),则将对其进行更新,而在其他情况下,将其插入。

10-07 19:21