2011-08-26 120 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

见注释过,静态成员是应用程序范围的变量,因此它们共享相同的字典,如果多个请求添加相同的密钥,就会抛出类似的错误。

相关问题