11

什么是增加或减少整数字段的干净、安全的方法。

我将 sql server 2012 与 entityframework 5.x 结合使用

我寻找一个等效于互锁增量/减量。

4

1 回答 1

20

标准方法是使用乐观并发。

假设您有一个简单的实体,其中包含Counter要递增或递减的整数字段:

public class SomeEntity
{
    public int SomeEntityId { get; set; }
    public int Counter { get; set; }
}

您可以将Counterthen 标记为并发令牌。使用 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 过滤,而且还通过 的旧值进行过滤,基本上类似于:。CounterFindCounterCounterWHERECounterWHERE SomeEntityId = someEntityId AND Counter = oldCounterWhenTheEntityHasBeenLoaded

catch块使用数据库中的当前Counter值重新加载实体,并且下一个循环尝试再次增加或减少重新加载的值,直到它成功而没有并发冲突。

于 2013-03-27T21:26:27.967 回答