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個工作角色/線程從多個源執行相同的操作,並將其全部導入同一個數據庫。 –