2011-08-26 123 views
1

我收到錯誤「已添加具有相同密鑰的項目。」當許多用戶嘗試同時訪問生產中的同一頁面時,我會隨機出現此錯誤。 在代碼中,docid被傳遞並向用戶顯示相關幫助。由於每個用戶都在查看相同的頁面,因此所有用戶都會傳遞相同的ID。有Linq-已添加具有相同密鑰的隨機項目錯誤

堆棧跟蹤,並提到線的烴源代碼給出如下

public string DocDescription(int docid) 
     { 
      DocumentRepository _Documentrepository = new DocumentRepository();    
      return _Documentrepository.GetDocDescription(docid); 
     } 

    } 


public string GetDocDescription(int DocID) 
     { 
      if (DocID != 0) 
       return db.sysDocuments.SingleOrDefault(p => p.DocumentID == DocID).Description==null?"No Description Available":db.sysDocuments.SingleOrDefault(p => p.DocumentID == DocID).Description; 
      else 
       return "No Description Available"; 
     } 

堆棧跟蹤摘錄在此調用沒有插入操作:

System.Web.HttpException (0x80004005): Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper'. ---> System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.Web.HttpException (0x80004005): Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'. ---> System.ArgumentException: An item with the same key has already been added. 
    at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) 
    at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) 
    at System.Data.Linq.DataContext.GetTable(MetaTable metaTable) 
    at System.Data.Linq.DataContext.GetTable[TEntity]() 
    at UserManagement.Models.DocumentRepository.GetDocDescription(Int32 DocID) in D:\Myproj\UserManagement\UserManagement\Models\DocumnetRepository.cs:line 109 
    at lambda_method(Closure , ControllerBase , Object[]) 
    at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) 
    at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) 
    at Castle.Proxies.ControllerActionInvokerProxy.InvokeActionMethod_callback(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
    at Castle.Proxies.Invocations.ControllerActionInvoker_InvokeActionMethod.InvokeMethodOnTarget() 
    at Castle.DynamicProxy.AbstractInvocation.Proceed() 
    at Glimpse.Net.Interceptor.InvokeActionMethodInterceptor.Intercept(IInvocation invocation) 
    at Castle.DynamicProxy.AbstractInvocation.Proceed() 
+1

GetDocDescription方法中db的作用域是什麼?那是你的數據庫上下文?我假設多個用戶正在嘗試同時加載相同的數據,並且由於'db'變量在用戶之間共享,因此您會得到此異常。 – thekip

+1

我的數據庫是靜態的,我把它改爲私有。我認爲它應該解決這個問題 – Tassadaque

回答

4

從你的代碼和註釋中,我知道你將db上下文存儲在一個靜態變量中。與實體一起工作時,這通常是一個糟糕的主意。

  1. DbContext不是線程安全的。因此,多個使用您網站的用戶會在上下文中導致此類錯誤。

  2. 處理上下文的一般建議是更喜歡短命的上下文。所以,只需創建一個新實例,當你需要時,然後忘記它。對於網站來說,使用像Unity,Castle.Winsdor等控件容器的反轉是非常常見的,並且將其配置爲每個Web請求爲您的DbContext返回一個實例。這將爲您提供足夠的性能,因此當前請求所需的所有實體都被緩存,並且不會同時導致線程問題。

1

見註釋過,靜態成員是應用程序範圍的變量,因此它們共享相同的字典,如果多個請求添加相同的密鑰,就會拋出類似的錯誤。

相關問題