Tassadaque
Tassadaque

Reputation: 8199

Linq- Random Item with same key has already been added Error

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()

Upvotes: 1

Views: 2726

Answers (2)

Vladimir Perevalov
Vladimir Perevalov

Reputation: 4159

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.

  1. DbContext is not thread safe. So, multiple users working with your site will cause such errors in context.

  2. 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.

Upvotes: 4

thekip
thekip

Reputation: 3768

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.

Upvotes: 1

Related Questions