可以 EntityState.Modified 导致执行插入操作
Could EntityState.Modified cause Insert operation to be performed
我正在阅读以下关于 entity framework 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);
}
此代码将涵盖这三个条件:-
- 如果用户清除了 office assignment 并且它原来有一个值,则必须移除并删除 OfficeAssignment 实体。
- 如果用户输入的办公室分配值最初为空,则您必须创建一个新的 OfficeAssignment 实体。
- 如果用户更改办公室分配的值,您必须更改现有 OfficeAssignment 实体中的值。
这是否意味着
db.Entry(instructorToUpdate).State = EntityState.Modified;
如果 Instructor 没有 prevouse OfficeAssignment 对象,将导致对 OfficeAssignment 记录执行插入语句?管理它的规则是什么?
这是完整的模型图:-
基本上有两种方法可以通过 EF 持久化实体。
A. 将其直接添加到 Dbset 中,并添加您希望它具有的其他关系。
Entity e = new Entity();
e.ForeignEntityId = 123;
context.Entities.Add(e);
context.SaveChanges();
B. 将其附加到现有实体,如果该实体 is/was 未跟踪,则将该实体标记为“已修改”。
Entity e = new Entity();
ForeignEntity fe = context.Find(...);
//Only needed if 'fe' was untracked
//context.Entry(fe).State = EntityState.Modified;
fe.Entity = e;
context.SaveChanges();
你问题中给出的方式是第二种方式。这一切都是为了让 "new" 对象出现在代表您的数据库中所有被跟踪的 EF 实体的对象图中。
DbContext.Entry
方法用于执行 显式加载 ,这意味着它使您可以访问 DbContext 拥有的关于实体的所有信息。这超出了存储在实际实体属性中的值,包括实体 状态 和每个 属性 检索时的原始值等内容来自数据库。
当您调用 TryUpdateModel
方法时,它将使用模型绑定器中的值更新属性(您将它们的名称作为参数传递)。这些属性之一是 OfficeAssignment
,它也已更新。如果在您看来您没有输入 Location
,那么您没有理由创建一个新的 OfficeAssigment
(这就是您需要做的 instructorToUpdate.OfficeAssignment = null;
,因为即使您不如果不输入新的 Location
,您将拥有 OfficeAssignment
的实例)。如果您添加一个新的 Location
,您将创建一个新的 OfficeAssignment
,如果您修改了 Location
,那么您将修改它的值。
当你这样做时:
db.Entry(instructorToUpdate).State = EntityState.Modified;
您将在实体上设置一个标志,表明它已被更改。当调用 SaveChanges
方法时,Modified
标志导致 Entity Framework 创建 SQL 语句来更新数据库行。数据库行的所有列都将更新,包括用户未更改的列,并发冲突将被忽略。为了更好地理解发生了什么,您可以将 Instructor
实例看成一棵树。 Code First 认识到您有导航 属性,因此需要更新或插入(视情况而定)。如果 OfficeAssignment
与 default(int)
有 Id
不同(我认为这是一个整数),那么它将被更新,在其他情况下,它将被插入。
是的,可以加载 DbContext.Entry 方法,并且可以用于进行如上所述的显式加载
我会建议宁愿做删除和插入,直到你没有实时修改的需要。
{
//Remove existing data
modelname existingobj = dbobj.tablename.Find(id);
dbobj.tablename.Remove(existingobj);
dbobj.SaveChanges();
//Add data
dbobj.Entry(existingobj).State = EntityState.Added;
dbobj.SaveChanges();
}
我正在阅读以下关于 entity framework 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);
}
此代码将涵盖这三个条件:-
- 如果用户清除了 office assignment 并且它原来有一个值,则必须移除并删除 OfficeAssignment 实体。
- 如果用户输入的办公室分配值最初为空,则您必须创建一个新的 OfficeAssignment 实体。
- 如果用户更改办公室分配的值,您必须更改现有 OfficeAssignment 实体中的值。
这是否意味着
db.Entry(instructorToUpdate).State = EntityState.Modified;
如果 Instructor 没有 prevouse OfficeAssignment 对象,将导致对 OfficeAssignment 记录执行插入语句?管理它的规则是什么?
这是完整的模型图:-
基本上有两种方法可以通过 EF 持久化实体。
A. 将其直接添加到 Dbset 中,并添加您希望它具有的其他关系。
Entity e = new Entity();
e.ForeignEntityId = 123;
context.Entities.Add(e);
context.SaveChanges();
B. 将其附加到现有实体,如果该实体 is/was 未跟踪,则将该实体标记为“已修改”。
Entity e = new Entity();
ForeignEntity fe = context.Find(...);
//Only needed if 'fe' was untracked
//context.Entry(fe).State = EntityState.Modified;
fe.Entity = e;
context.SaveChanges();
你问题中给出的方式是第二种方式。这一切都是为了让 "new" 对象出现在代表您的数据库中所有被跟踪的 EF 实体的对象图中。
DbContext.Entry
方法用于执行 显式加载 ,这意味着它使您可以访问 DbContext 拥有的关于实体的所有信息。这超出了存储在实际实体属性中的值,包括实体 状态 和每个 属性 检索时的原始值等内容来自数据库。
当您调用 TryUpdateModel
方法时,它将使用模型绑定器中的值更新属性(您将它们的名称作为参数传递)。这些属性之一是 OfficeAssignment
,它也已更新。如果在您看来您没有输入 Location
,那么您没有理由创建一个新的 OfficeAssigment
(这就是您需要做的 instructorToUpdate.OfficeAssignment = null;
,因为即使您不如果不输入新的 Location
,您将拥有 OfficeAssignment
的实例)。如果您添加一个新的 Location
,您将创建一个新的 OfficeAssignment
,如果您修改了 Location
,那么您将修改它的值。
当你这样做时:
db.Entry(instructorToUpdate).State = EntityState.Modified;
您将在实体上设置一个标志,表明它已被更改。当调用 SaveChanges
方法时,Modified
标志导致 Entity Framework 创建 SQL 语句来更新数据库行。数据库行的所有列都将更新,包括用户未更改的列,并发冲突将被忽略。为了更好地理解发生了什么,您可以将 Instructor
实例看成一棵树。 Code First 认识到您有导航 属性,因此需要更新或插入(视情况而定)。如果 OfficeAssignment
与 default(int)
有 Id
不同(我认为这是一个整数),那么它将被更新,在其他情况下,它将被插入。
是的,可以加载 DbContext.Entry 方法,并且可以用于进行如上所述的显式加载
我会建议宁愿做删除和插入,直到你没有实时修改的需要。
{
//Remove existing data
modelname existingobj = dbobj.tablename.Find(id);
dbobj.tablename.Remove(existingobj);
dbobj.SaveChanges();
//Add data
dbobj.Entry(existingobj).State = EntityState.Added;
dbobj.SaveChanges();
}