我收到错误“已经添加了具有相同密钥的项目。”当许多用户尝试同时访问生产中的同一页面时,我会随机收到此错误。 在代码中传递docid并向用户显示相关帮助。当每个用户正在查看同一页面时,所有用户都会传递相同的ID。此调用中没有插入操作
上述行的堆栈跟踪和源代码如下:
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";
}
Stack Trace摘录:
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()
答案 0 :(得分:4)
从您的代码和注释中,我得到您将db上下文存储在静态变量中。在与实体合作时,这通常是个坏主意。
DbContext不是线程安全的。因此,使用您网站的多个用户都会在上下文中导致此类错误。
使用上下文的一般建议是偏好短期上下文。所以只需在需要时创建一个新实例,然后忘记它。对于网站,使用Unity,Castle.Winsdor等控制容器的反转是很常见的,并将其配置为为每个Web请求返回一个实例,用于DbContext。这将为您提供足够的性能,因此当前请求所需的所有实体都会被缓存,并且不会同时导致线程问题。
答案 1 :(得分:1)
请参阅注释,静态成员是应用程序范围的变量,因此他们共享相同的字典,如果多个请求添加相同的密钥,则会抛出这样的错误。