4

如果我使用实体框架作为后端的MVC的Web API一个控制器可以是这个样子(快速样机):实体框架,防止重复的记录,同时连接

public class PersonController : ApiController 
    { 
     [HttpPost] 
     public void AddPerson(Person val) 
     { 
      DbContext context = new DbContext(); 
      if(!context.Persons.Any(x=>x.Email == val.Email)) 
      { 
       context.Persons.Add(val) 
       context.SaveChanges(); 
      } 
     } 
    } 

的问题是,如果这操作被称为50次,每隔几秒100次(可能不是一个好例子),多个条目可能被添加到同一个电子邮件地址的可能性很高。

如果val参数是的Person列表,你可以检查changetracker,看是否已经添加了电子邮件地址的人之前,你SaveChanges()但这并不当你有很多不同来源的呼叫的工作。

你不能有一个静态的DBContext因为它会抛出一个异常,说它很忙。

一个想法我没想到的是相同的设置,但是具有返回dbcontext的实例(同一个实例),但一个静态方法上有一个lock()创造一种像队列,但是这可能会影响性能的ISN这不是一个好主意。

你如何解决这个问题?

该示例与我正在做的事情无关,但仅仅是一些简单的解释场景。它不一定是特定的,我猜。

感谢

史蒂夫

+0

是什么让一个新人变得独特?是否允许多个使用相同电子邮件地址的人员?如果否,那么电子邮件属性的唯一限制肯定会有所帮助。你也应该考虑为什么这个操作经常被重复的信息调用。 – elolos

+0

我不只是需要防止重复,我可能需要拉和现有的链接,可以创建0.00001ms之前,并将其链接到一个新的记录。这个例子显然不是最好的。 –

回答

0

如果您不需要实时更新数据库,那么您也可以对每个请求进行排队,并且只让一个工作人员处理排队的请求。

+0

这是我唯一的选择,但想避免这样的事情,因为它可以减慢它。 –

+0

只要避免锁定以避免支付其间接费用,如果您无法放弃并行性,您可以设置“主要”工作人员将一组消息出列并让后者过滤掉重复,然后为每个独特的讯息。这种设置还可以消除Web服务的负担,因为处理负担将传递给工作人员。 – geno

1

我不知道谁或什么消费这个服务。但为什么同一个用户每秒会被多次添加? 具有相同电子邮件地址的人员的多次发布应指明同一人,但其他特性可能不同。问题在于你想要“赢”的是第一还是最后?

一个简单而有效的方法是在数据库的Email属性上设置唯一的约束,并以适当的方式处理异常。

+0

它实际上是一个数据导入,它将5-20个工作角色/线程从多个源执行相同的操作,并将其全部导入同一个数据库。 –