Linq-已添加具有相同密钥的随机项目错误
我收到错误“已添加具有相同密钥的项目。”当许多用户尝试同时访问生产站点上的同一页面时,我会随机收到此错误。 在代码中传递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";
}
堆栈跟踪摘录:
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()
I am getting error "An item with the same key has already been added." I get this error randomly when many user try to access the same page on site in production at the same time.
In the code docid is passed and relevant help is displayed to user. As each user is viewing the same page so same ID is passed for all users. There is no insert operation in this call
Stack trace and souce code of mentioned line is given as follows
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 excerpt:
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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从您的代码和注释中,我了解到您将数据库上下文存储在静态变量中。当与实体合作时,这通常是一个坏主意。
DbContext 不是线程安全的。因此,多个用户使用您的站点将导致上下文中出现此类错误。
使用上下文的一般建议是更喜欢短暂的上下文。因此,只需在需要时创建一个新实例,然后就可以忘记它了。对于网站,使用 Unity、Castle.Winsdor 等控制反转容器,并将其配置为每个 Web 请求为 DbContext 返回一个实例是很常见的。这将为您提供足够的性能,因此当前请求所需的所有实体都会被缓存,并且不会同时导致线程问题。
From your code and comments, I get that you store db context in a static variable. This is generally a bad idea when working with entities.
DbContext is not thread safe. So, multiple users working with your site will cause such errors in context.
The general suggestion for working with context is to prefer short lived context. So just create a new instance, when you need it, and then forget it. For the web sites, it is quite common to use inversion of control container like Unity, Castle.Winsdor etc, and configure it to return one instance per web request for your DbContext. This will give you enough performance, so all entities needed for the current request are cached, and will not cause threading issues at the same time.
也请参阅注释,静态成员是应用程序范围的变量,因此它们共享相同的字典,如果多个请求添加相同的键,则可能会抛出这样的错误。
See comment too, static members are application scoped variables thus they're sharing the same dictionary which can throw errors like this if multiple requests add the same key.