Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to safely increment a counter in Entity Framework

Let's say I have a table that tracks the number of times a file was downloaded, and I expose that table to my code via EF. When the file is downloaded I want to update the count by one. At first, I wrote something like this:

var fileRecord = (from r in context.Files where r.FileId == 3 select r).Single();
fileRecord.Count++;
context.SaveChanges();

But then when I examined the actual SQL that is generated by these statements I noticed that the incrementing isn't happening on the DB side but instead in my memory. So my program reads the value of the counter in the database (say 2003), performs the calculation (new value is 2004) and then explicitly updates the row with the new Count value of 2004. Clearly this isn't safe from a concurrency perspective.

I was hoping the query would end up looking instead like:

UPDATE Files SET Count = Count + 1 WHERE FileId=3

Can anyone suggest how I might accomplish this? I'd prefer not to lock the row before the read and then unlock after the update because I'm afraid of blocking reads by other users (unless there is someway to lock a row only for writes but not block reads).

I also looked at doing a Entity SQL command but it appears Entity SQL doesn't support updates.

Thanks

like image 285
Dejas Avatar asked Mar 11 '11 01:03

Dejas


1 Answers

You're certainly welcome to call a stored procedure with EF. Write a sproc with the SQL you show then create a function import in your EF model mapped to said sproc.

like image 155
Jesse C. Slicer Avatar answered Oct 21 '22 04:10

Jesse C. Slicer