如何INC / DEC多用户在实体框架5安全(how to inc/dec multi user s

2019-08-18 01:46发布

什么是递增或递减一个整数字段一个干净,安全的方式。

我使用SQL Server 2012结合的EntityFramework 5.x的

我找一个相当于互锁递增/递减。

Answer 1:

标准的方式是使用开放式并发。

也就是说,如果你有一个整数字段一个简单的实体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从数据库中值,下一个循环试图递增或递减再次重装的值,直到成功为止没有并发冲突。



文章来源: how to inc/dec multi user safe in entity framework 5