如何在实体框架5中增加/减少多用户安全 [英] how to inc/dec multi user safe in entity framework 5

查看:36
本文介绍了如何在实体框架5中增加/减少多用户安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What is a clean, safe way to increment or decrement an integer field.

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

i use sql server 2012 in combination with entityframework 5.x

我正在寻找与互锁的增量/减量等效的方法。

I look for an equivalent to interlocked increment / decrement.

推荐答案

是使用乐观并发。

说,您有一个简单的实体,其整数字段 Counter 递增或递减:

Say, you have a simple entity with an integer field Counter that you want to increment or decrement:

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

您可以标记计数器然后作为并发令牌。使用Fluent API,它是:

You could mark the Counter then as a concurrency token. With Fluent API it is:

modelBuilder.Entity<SomeEntity>()
    .Property(s => s.Counter)
    .IsConcurrencyToken();

然后您可以递增或递减 Counter 例如,像这样:

Then you can increment or decrement the Counter for example like so:

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 (在此示例中,使用 Find 可以是任何其他查询)与数据库中 Counter 的值不同时, UPDATE语句在数据库中执行,这意味着 Counter 同时已被另一个用户修改。从技术上讲,这是通过生成的UPDATE语句的扩展 WHERE 子句实现的,该子句不仅尝试根据ID进行过滤,而且还尝试根据 Counter的旧值进行过滤,基本上类似: WHERE SomeEntityId = someEntityId AND Counter = oldCounterWhenTheEntityHasBeenLoaded

SaveChanges will fail with a DbUpdateConcurrencyException if the value of Counter when the entity has been loaded (with Find in this example, could be any other query) differs from the value of Counter in the database when the UPDATE statement is executed in the database which would mean that the Counter has been modified by another user in the meantime. Technically this is achieved by an extended WHERE clause of the generated UPDATE statement that tries to filter not only by the Id but also by the old value of Counter, basically something like: WHERE SomeEntityId = someEntityId AND Counter = oldCounterWhenTheEntityHasBeenLoaded.

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

The catch block reloads the entity with the current Counter value from the database and the next loop tries to increment or decrement the reloaded value again until it succeeds without concurrency violation.

这篇关于如何在实体框架5中增加/减少多用户安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆