Asp.net mvc 防止使用实体框架同时插入来自客户端的相同记录
当从Clint调用时,我有一个Api配置,它插入一个电话号码和当前日期时间。 在我的办公室里,我有4个客户同时调用此api,这将导致4个插入数据,因此,我添加了调节器以防止这种情况,代码如下:Asp.net mvc 防止使用实体框架同时插入来自客户端的相同记录,asp.net-mvc,entity-framework,asp.net-core,Asp.net Mvc,Entity Framework,Asp.net Core,当从Clint调用时,我有一个Api配置,它插入一个电话号码和当前日期时间。 在我的办公室里,我有4个客户同时调用此api,这将导致4个插入数据,因此,我添加了调节器以防止这种情况,代码如下: public bool IsExistIn10Seconds(string number) { var item = DbContext.Histories .Where(o => o.Number == Number &&
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();
}
如果项
变量中存在任何记录,这意味着记录已经添加,但此解决方案不起作用,并且处于生产阶段,它仍然添加4条记录。
是否有任何解决方案可以防止同时进行多次插入(Entity Framework,MVC Core 2.0)如果您希望某个字段具有唯一性,可以在该字段上添加唯一索引。这将防止表中出现重复。尝试多次插入时将出现异常。
另一种方法是,可以使用具有可序列化隔离级别的db事务在一个事务中读取现有行(检查是否存在)并写入新行。它还将导致多次插入时出现异常。检查数据库中是否有与您尝试添加的内容具有相同详细信息的重复条目。如果不是,那么它是一个新版本,你应该添加它,如果是,那么它是一个副本,你应该做任何你想处理的情况
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();
}
I使用锁定原理:
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();
}
}
如果它们是子记录,例如电话号码Entry是具有历史记录的父项,则可以通过父项电话号码强制添加,并在父项上使用时间戳属性进行并发控制。如果只是单个记录,db唯一索引可能是最好的。如果您需要在应用程序中执行此操作,您可能需要通过保留模式或锁定来强制执行。请提供完整的代码片段?您提到插入记录,但没有插入记录的代码。@Luke问题更新!您试图解决的问题到底是什么?@AndreiDragotoniu因为所有客户端都在同一时间添加调用api,所有客户端都在同一时间检查是否存在记录,并且由于结果所有客户端都不存在,它们将向数据库添加相同的记录!很好,这是一个选项,但它有一些限制。任何时候都有一个正在运行的进程。一些线程将等待。最后,它不能防止重复,它可以从代码中的其他地方插入。