什么是增加或减少整数字段的干净、安全的方法。
我将 sql server 2012 与 entityframework 5.x 结合使用
我寻找一个等效于互锁增量/减量。
什么是增加或减少整数字段的干净、安全的方法。
我将 sql server 2012 与 entityframework 5.x 结合使用
我寻找一个等效于互锁增量/减量。
标准方法是使用乐观并发。
假设您有一个简单的实体,其中包含Counter
要递增或递减的整数字段:
public class SomeEntity
{
public int SomeEntityId { get; set; }
public int Counter { get; set; }
}
您可以将Counter
then 标记为并发令牌。使用 Fluent API 它是:
modelBuilder.Entity<SomeEntity>()
.Property(s => s.Counter)
.IsConcurrencyToken();
然后你可以Counter
像这样增加或减少例子:
public void IncDecCounter(int someEntityId, bool dec)
{
using (var context = new MyContext())
{
var someEntity = context.SomeEntities.Find(someEntityId);
if (someEntity != null)
{
bool saveFailed;
do
{
saveFailed = false;
if (dec)
--someEntity.Counter;
else
++someEntity.Counter;
try
{
context.SaveChanges();
}
catch (DbUpdateConcurrencyException e)
{
saveFailed = true;
e.Entries.Single().Reload();
}
} while (saveFailed);
}
}
}
SaveChanges
如果加载实体时DbUpdateConcurrencyException
的值(在本例中,可以是任何其他查询)与在数据库中执行 UPDATE 语句时数据库中的值不同,则将失败,这意味着已经同时被其他用户修改。从技术上讲,这是通过生成的 UPDATE 语句的扩展子句来实现的,该子句不仅尝试通过 Id 过滤,而且还通过 的旧值进行过滤,基本上类似于:。Counter
Find
Counter
Counter
WHERE
Counter
WHERE SomeEntityId = someEntityId AND Counter = oldCounterWhenTheEntityHasBeenLoaded
该catch
块使用数据库中的当前Counter
值重新加载实体,并且下一个循环尝试再次增加或减少重新加载的值,直到它成功而没有并发冲突。