Lar*_*335 8 c# entity-framework asp.net-web-api
我在Web客户端的Web API服务器上使用EF 6.x(代码优先),我需要实现并发处理.问题是我甚至无法获得EF来生成异常.
我发现的大多数示例似乎都没有使用"分离实体",其中DTO被发送到Web客户端,在那里它被更新,然后在以后保存回服务器(这是我的方案).
假设我有公司记录:
public class Company
{
int CompanyId { get; set; }
string CompanyName { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
1)用户A拉出公司Id= 0,RowVersion为0x0000000000002B0A
2)我运行UPDATE Company SET CompanyName = 'Acme Changed, Inc.' WHERE CompanyId = 0模拟另一个用户的更改. RowVersion更改为0x0000000000002B0B
3)用户A将CompanyName更改为"Acme,The Great!" 并单击保存(从浏览器)
4)公司DTO到达Web API服务器CompanyName="Acme,The Great!" 和旧RowVersion= 0x0000000000002B0A
5)我从数据库中检索公司记录,更新并保存:
public void UpdateCompany(Company updatedCompany)
{
var dbCompany = Context.Companies.SingleOrDefault(r => r.CompanyId == updatedCompany.CompanyId);
dbCompany.CompanyName = updatedCompany.CompanyName;
dbCompany.RowVersion = updatedCompany.RowVersion; // Set RowVersion to the passed in original RowVersion 0x0000000000002B0A
try
{
DbContext.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
// Expected: exception thrown (but does not happen).
}
}
Run Code Online (Sandbox Code Playgroud)
它只是将记录和更新保存RowVersion到0x0000000000002B0C ,而不是并发异常.
我错过了什么?
我需要一种方法来检测更改,删除等,以防止保存脏数据.我想我可以滚动自己的检查,但实际的对象很复杂,有很多嵌套的子对象(一个或多个级别).
关于此的最佳实践的任何指针也将受到赞赏......
Lar*_*335 11
我得到了这个工作.在我的问题的第5步中,我改变了这一行:
dbCompany.RowVersion = updatedCompany.RowVersion;
Run Code Online (Sandbox Code Playgroud)
对此:
Context.Entry(dbCompany).OriginalValues["RowVersion"] = updatedCompany.RowVersion;
Run Code Online (Sandbox Code Playgroud)
现在EF在尝试保存脏数据时抛出DbUpdateConcurrencyException!