什么是递增或递减一个整数字段一个干净,安全的方式。
我使用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
则作为并发令牌。 用流利的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
如果值Counter
,当实体已经被加载(与Find
在这个例子中,可以是任何其他查询)从的值不同Counter
UPDATE语句时将在数据库中这将是在数据库中执行意味着Counter
已被在此期间其他用户修改。 从技术上讲,这是通过扩展实现WHERE
试图不仅由ID也受到旧值过滤产生的UPDATE语句的WHERE子句Counter
,基本上是这样的: WHERE SomeEntityId = someEntityId AND Counter = oldCounterWhenTheEntityHasBeenLoaded
。
该catch
块重新加载当前实体Counter
从数据库中值,下一个循环试图递增或递减再次重装的值,直到成功为止没有并发冲突。