如何在Entity Framework中安全地增加计数器

时间:2011-03-11 01:44:10

标签: entity-framework entity-framework-4

假设我有一个跟踪文件下载次数的表,并通过EF将该表暴露给我的代码。下载文件时,我想将计数更新一次。起初,我写了这样的话:

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

但是当我检查这些语句生成的实际SQL时,我注意到增量不是发生在数据库端,而是发生在我的内存中。所以我的程序读取数据库中的计数器值(比如2003),执行计算(新值是2004),然后使用新的Count值2004显式更新行。显然,从并发角度来看,这是不安全的

我希望查询最终看起来像:

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

有谁能建议我怎么做到这一点?我不希望在读取之前锁定行,然后在更新后解锁,因为我害怕阻止其他用户读取(除非有人只为写入锁定行而不是块读取)。

我还看了一下Entity SQL命令,但看起来Entity SQL不支持更新。

谢谢

2 个答案:

答案 0 :(得分:1)

欢迎您使用EF调用存储过程。使用您显示的SQL编写一个sproc,然后在映射到所述sproc的EF模型中创建一个函数import。

答案 1 :(得分:0)

您需要进行一些锁定才能使其正常工作。但是你可以减少锁定量。

当您读取计数并想要更新它时,您必须将其锁定,这可以通过将读取和更新放在事务范围内来完成。这将保护您免受竞争条件的影响。

当您读取该值并且只是想要读取它时,可以使用事务隔离级别ReadUncommited执行此操作,此读取将不会被上面的读/写锁定锁定。