Note that there are some explanatory texts on larger screens.

plurals
  1. POWCF Entity Framework Concurrency
    text
    copied!<p>I've got a WCF service that is making calls to my Entity Framework Repository classes to access data. I'm using Entity Framework 4 CTP, and am using my own POCO objects rather than the auto generated entity objects.</p> <p>The context lifetime is limited to the method call. For Select/Insert and Update methods I create the context and dispose of it in the same method returning disconnected entity objects. </p> <p>I'm now trying to work out the best way to handle concurrency issues. For example this is what my update method looks like</p> <pre><code>public static Sale Update(Sale sale) { using (var ctx = new DBContext()) { var SaleToUpdate = (from t in ctx.Sales where t.ID == sale.ID select t).FirstOrDefault(); if (SaleToUpdate == null) throw new EntityNotFoundException(); ctx.Sales.ApplyCurrentValues(sale); ctx.SaveChanges(); return sale; } } </code></pre> <p>This works fine, but because I'm working in a disconnected way no exception is thrown if the record has been modified since you picked it up. This is going to cause concurrency issues.</p> <p>What is the best way to solve this when your using the entity framework over WCF and are not keeping a global context? </p> <p>The only method I can think of is to give my objects a version number and increment it each time a save is called. This would then allow me to check the version hasnt changed before I save. Not the neatest solution I know and would still allow the client to change their version number which I really don't want them to be able to do.</p> <p><strong>EDIT :</strong> Using Ladislav Mrnka's suggestion of RowVersion fields in my entities, each of my entities now has a field called Version of type RowVersion. I then changed my Update method to look like this.</p> <pre><code>public static Sale Update(Sale sale) { using (var ctx = new DBContext()) { var SaleToUpdate = (from t in ctx.Sales where t.ID == sale.ID select t).FirstOrDefault(); if (SaleToUpdate == null) throw new EntityNotFoundException(); if (!sale.Version.SequenceEqual(SaleToUpdate .Version)) throw new OptimisticConcurrencyException("Record is out of date"); ctx.Sales.ApplyCurrentValues(sale); ctx.SaveChanges(); return sale; } } </code></pre> <p>It seems to work but if I should be doing it differently please let me know. I tried to use Entity Frameworks built in concurrency control by setting the version fields concurrency mode to fixed, unfortunately this didn't work as when I did the query to get the unchanged SaleToUpdate it picked up its version and used that to do its concurrency check which is obviously current. It feels like the entity framework might be missing something here.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload