实体框架,防止重复记录,同时连接

时间:2014-03-07 09:51:58

标签: c# entity-framework asp.net-web-api asp.net-web-api2 duplicates

如果我使用实体框架作为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()创建一种类似的队列但这可能影响表现并不是一个好主意。

你如何解决这个问题?

这个例子与我正在做的事情无关,只是解释场景的简单方法。我猜它也不一定具体。

由于

史蒂夫

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

在电子邮件表上放置一个唯一约束索引? 要么 将SQL事务隔离级别更改为Serializable? 要么 锁定一个静态对象,这样一个方法一次可以通过该方法吗?

http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

答案 2 :(得分:0)

如果您不需要实时更新数据库,您也可以为每个请求排队,只需要一个工作人员来处理排队的请求。