2012-01-31 57 views
1

我有一個EF代碼優先生成的數據庫。數據處理使用DbContext完成。 Asp.net應用程序中的IoC容器生成一個DbContext實例,即BL對象依賴於每個線程。這是一個隨Web應用程序一起加載的後臺任務類。從不同線程保存更改時的EF協議跟蹤

每隔一段時間(如每隔10分鐘),後臺線程通過在事務範圍內調用myDbContext.Add將一個項目添加到Incidents列表中。

同時,好像如果Incidents之一是myDbContext在「Web請求的線程」改變,即使改變被保存到了片刻的數據庫,它們越來越被集Incidents的覆蓋,在用戶使用網頁更改Incident之前,用戶通過背景線拉動了這些內容。

這看起來像一個併發問題(我沒有實現任何像Timestamp列一樣的協調)。

我的問題是:不應該後臺線程只保存更改的數據(在我的情況下,添加一個新的事件),留下整個事件集合?如果確實如此,我的問題來源是其他地方。從後臺線程

代碼:

using (var transaction = new TransactionScope()) 
      { 
       foreach (var scheduledTask in _db.ScheduledTasks) 
       { 
        if (scheduledTask.NextExecuteAfterDate == null) 
        { 
         PopulateNextExecuteAfterDate(scheduledTask); 
         shouldSaveChanges = true; 
        } 

        if (DateTime.Now > scheduledTask.NextExecuteAfterDate) 
        { 
         RegisterRecurringTicket(scheduledTask); 
         CalculateNextTime(scheduledTask); 
         shouldSaveChanges = true; 
        } 
       } 

       if (shouldSaveChanges) _db.SaveChanges(); 
       transaction.Complete(); 
      } 

的代碼在子程序RegisterRecurringTicket(scheduledTask);增加了項目的事件集合。當調用_db.SaveChanges();時,看起來事件的集合被舊集合覆蓋,將用戶界面生成的更改投棄置於事件集合。如果是這樣,我該如何解決這個問題?

回答

0

問題是我正在使用PerThreadScopeDbContext進樣。這導致了我的ASP.NET應用程序的意外行爲。設置Ninject模塊,以解決中的DbContext問題。

0

只需調用myDbContext.Incidents.ToList()不會導致數據庫中的任何內容被覆蓋。 然而,我可以很容易想象這樣的情況:

// My Incident tracker 
IEnumerable<Incident> CurrentIncidents {get{return myDbContext.Incidents.ToList();}} 

// Meanwhile, in another class on the same thread... 
foreach(var incident in IncidentTracker.CurrentIncidents) 
{ 
    var claims = myDbContext.Claims.Where(c => c.IncidentId == incident.IncidentId); 
    foreach(var claim in claims) 
    { 
     Process(claim); 
    } 
    incident.Processed = true; 
} 
myDbContext.SaveChanges(); 

在上面的例子中,即使你不拉Incident小號直接從myDbContext,因爲這兩個類得到了相同的情況下注入到他們,致電SaveChanges()實際上影響(您想要改變的)索賠和事件(您沒有)。

是否有可能發生這樣的事情?

+0

是的。自從我發現,我已經更新了問題主體,我誤導了問題讀者關於問題設置。請看一下。 – 2012-01-31 23:26:05