I am using EF 6.x (code-first) on a Web API server with web clients and I need to implement concurrency handling. The problem is that I cannot even get EF to generate an exception.
Most examples that I have found seems to not be using "detached entities", where the DTO is sent to a web client where it is updated and then saved back to the server at a later time (which is my scenario).
Let's say I have a Company record:
public class Company { int CompanyId { get; set; } string CompanyName { get; set; } [Timestamp] public byte[] RowVersion { get; set; } }
1) User A pulls up company with Id
= 0, RowVersion
is 0x0000000000002B0A
2) I run UPDATE Company SET CompanyName = 'Acme Changed, Inc.' WHERE CompanyId = 0
to simulate a change by another user. RowVersion
changes to 0x0000000000002B0B
3) User A changes CompanyName to "Acme, The Great!" and clicks Save (from browser)
4) The Company DTO arrives at Web API server with CompanyName
= "Acme, The Great!" and the old RowVersion
= 0x0000000000002B0A
5) I retrieve the Company record from the DB, update it and save it:
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). } }
Instead of a concurrency exception, it just saves the record and updates RowVersion
to 0x0000000000002B0C.
What am I missing?
I need a way to detect changes, deletion, etc. to prevent saving dirty data. I guess I could roll my own checks, but the actual objects are complex with many nested child objects (one or more levels).
Any pointers on best practices on this would also be appreciated...