我正在从一本书中使用C#中的EF进行ASP.NET MVC项目,这部分是为了避免从不同的会话同时更新实体。 这本书很棒但不幸的是在这一部分解释是不够的,如果有人能帮我理解,我将不胜感激。 我会尝试省略不相关的代码。该模型基本上只有一个属性“Name”,所以它非常简单:
[HttpPost]
public ActionResult Edit(int? id, byte[] rowVersion)
{
string[] fieldsToBind = new string[] { "Name", "RowVersion" };
var categoryToUpdate = db.Categories.Find(id);
if (TryUpdateModel(categoryToUpdate, fieldsToBind))
{
try
{
db.Entry(categoryToUpdate).OriginalValues["RowVersion"] =
rowVersion;
db.SaveChanges();
return RedirectToAction("Index");
}
catch (DbUpdateConcurrencyException ex)
{//... and the code goes on to handle the concurrent update
// scenario
}
这是我不明白的: 如果TryUpdateModel方法成功更新了模型,并绑定了新值“Name”和“RowVersion”(由视图提供),为什么我必须包含以下行:db.Entry(categoryToUpdate).OriginalValues [“RowVersion” ] = rowVersion;?这条线究竟做了什么?为什么抛出异常需要它? 感谢
答案 0 :(得分:0)
这与EF内部工作方式有关。为此语句生成UPDATE命令时,EF将查找OriginalValues中存在RowVersion值的行。
需要添加该行,因为实体是使用以下行从DB加载的:
db.Categories.Find(id);
因为实体的最新值是使用此行从DB加载的,所以除非您更改存储在OriginalValues中的RowVersion值,否则不会出现并发异常。
如果未从DB加载实体并且通过将其附加到上下文来执行更新,那么就不需要在OriginalValues中设置RowVersion。