尽管更新冲突,但EF不会抛出DbUpdateConcurrencyException

我在Web客户端的Web API服务器上使用EF 6.x(代码优先),我需要实现并发处理。 问题是我甚至无法获得EF来生成exception。

我发现的大多数示例似乎都没有使用“分离实体”,其中DTO被发送到Web客户端,在那里它被更新,然后在以后保存回服务器(这是我的场景)。

假设我有公司记录:

public class Company { int CompanyId { get; set; } string CompanyName { get; set; } 1541627290 public byte[] RowVersion { get; set; } } 

1)用户A上拉公司, Id = 0, RowVersion为0x0000000000002B0A

2)我运行UPDATE Company SET CompanyName = 'Acme Changed, Inc.' WHERE CompanyId = 0 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). } } 

它只保存记录并将RowVersion更新为0x0000000000002B0C,而不是并发exception。

我错过了什么?

我需要一种方法来检测更改,删除等,以防止保存脏数据。 我想我可以滚动自己的检查,但实际的对象很复杂,有许多嵌套的子对象(一个或多个级别)。

关于此的最佳实践的任何指示也将受到赞赏……

我有这个工作。 在我的问题的第5步中,我改变了这一行:

 dbCompany.RowVersion = updatedCompany.RowVersion; 

对此:

 Context.Entry(dbCompany).OriginalValues["RowVersion"] = updatedCompany.RowVersion; 

现在EF在尝试保存脏数据时抛出DbUpdateConcurrencyException!

我正在使用Entity Framework的抽象,我无法访问EF上下文,但我发现了写作

updatedCompany.RowVersion.CopyTo(dbCompany.RowVersion, 0);

解决了这个问题。