防止使用实体框架同时插入来自客户端的相同记录

时间:2018-04-04 08:22:55

标签: asp.net-mvc entity-framework asp.net-core

我从Clint调用时有Api配置,它插入一个PhoneNumber&当前日期时间。 在我的办公室我有4个Clint同时调用这个api,这将导致4个插入数据,因此,我添加了调节器以防止这种情况,代码如下:

public bool IsExistIn10Seconds(string number)
{
    var item = DbContext.Histories
               .Where(o => o.Number == Number && 
                           o.EntryDateTime.DateTime >= DateTime.Now.AddSeconds(-10))
               .FirstOrDefault();
}

用于插入数据的代码:

public void Save(History model)
{
    var exist = _historyRepository.IsExistIn10Seconds(model.Number);
    if (exist) return;
    _historyRepository.Add(model);
    _historyRepository.Save();
}

如果item变量中存在任何记录,则表示记录已添加,但此解决方案无效,在生产阶段,仍会添加4条记录。 result after publish in production stage 是否有任何解决方案同时防止多个插入(实体框架,MVC核心2.0)

4 个答案:

答案 0 :(得分:2)

如果您想要某些字段的唯一性,可以在字段上添加唯一索引。这样可以防止表格中的欺骗行为。尝试多次插入时会有异常。 另一种方法是您可以使用具有可序列化隔离级别的db事务来读取现有行(检查存在)并在一个事务中写入新行。它还会导致多次插入时出现异常。

答案 1 :(得分:0)

检查数据库中是否有任何重复条目与您尝试添加的内容具有相同的详细信息。如果没有,那么它是一个新版本,您应该添加它,如果是,那么它是重复的,你应该做任何你想要处理的情况。

if (repository.Get(x => x.Major == newVersion.Major && 
    x.Minor == newVersion.Minor && x.Build == newVersion.Build)
    .Count() > 0)
{
     //notify the user that they are making a duplicate entry
}
else
{
     repository.SaveChanges();
}

More

答案 2 :(得分:0)

我使用锁定原则:

public class LockObject
{
    public static object LockObjectSatet = new object();
}

然后:

public void Save(History model)
{
    lock (LockObject.LockObjectSatet)
    {
        var exist = _historyRepository.IsExistIn10Seconds(model.Number);
        if (exist) return;
        _historyRepository.Add(model);
        _historyRepository.Save();
    }
}

答案 3 :(得分:0)

如果他们是儿童记录,例如电话号码entiry是具有历史记录的父级,您可以通过父电话号码强制添加,并在父级上使用时间戳属性进行并发控制。 http://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/concurrency。如果只是单个记录db唯一索引可能是最好的。如果您需要在app中执行此操作,则可能需要通过预留模式或锁定来强制执行。