Tassadaque
Tassadaque

Reputation: 8199

An item with the same key has already been added

I am getting this error randomly at the production server here is the stack trace of the error. I am using linq to sql and .net 4.0

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.EvoletDataContext.get_sysModules() in D:\MyProj\Models\datamdl.designer.cs:line 1294
   at UserManagement.Models.FilterRepository.GetModuleHead(String actionName) in D:\MyProj\Models\FilterRepository.cs:line 14
   at UserManagement.Models.DummyAttrib.OnAuthorization(AuthorizationContext filterContext) in D:\MyProj\Models\Filters.cs:line 44
   at Glimpse.Net.Plumbing.GlimpseAuthorizationFilter.OnAuthorization(AuthorizationContext filterContext)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.ExecuteCore()
   at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
   at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)
   at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__5()
   at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
   at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
   at System.Web.Mvc.MvcHandler.<>c__DisplayClasse.<EndProcessRequest>b__d()
   at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f)
   at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action)
   at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Code at line 14 is below. I have also included the datacontext

private EvoletDataContext db = new EvoletDataContext();

        public sysModule GetModuleHead(string actionName)
        {
            var val =  (from mod in db.sysModules
                        where
                        mod.ModuleActionResult.ToLower().Equals(actionName.ToLowerInvariant())
                    select mod).SingleOrDefault();
            return val;
    }

Code at line 44 is

public class DummyAttrib:FilterAttribute,IAuthorizationFilter
    {

        private readonly FilterRepository _filterRepository = new FilterRepository();
        public void OnAuthorization(AuthorizationContext filterContext) 
        {
            if (!filterContext.Controller.ControllerContext.IsChildAction && !filterContext.HttpContext.Request.IsAjaxRequest())
            {
                var cont = (ApplicationController)filterContext.Controller;
                                var modhead = _filterRepository.GetModuleHead(filterContext.RouteData.Values["action"].ToString());
                if (cont.DocumentID != 0 && modhead !=null) 
                {
                    if (_filterRepository.hasRightonModuleChildren(modhead.ModuleID, cont.RoleID))
                        return;
                }
                if (cont.DocumentID == 0 && !filterContext.RouteData.Values["action"].ToString().ToLowerInvariant().Equals("index"))
                {
                    filterContext.Result = new RedirectResult("/account.mvc/AccessDenied");
                    return;
                }

                if (!_filterRepository.hasRighton(cont.DocumentID, cont.RoleID))
                {
                    filterContext.Result = new RedirectResult("/account.mvc/AccessDenied");
                    return;
                }

            }
        }
    }

Upvotes: 9

Views: 13181

Answers (6)

Dan Nick
Dan Nick

Reputation: 132

I got the same issue in EF 4.1. with an existing application. What happened? The EF 4.1 requires the .net framework 4.0. Windows update replaced the .net framework 4.0 with 4.5 and I got the same error you got. The solution was to uninstall .net 4.5 and install .net 4.0. On the production machine you should set the windows to skip the update to 4.5.

Upvotes: 0

atulpatel.mca
atulpatel.mca

Reputation: 261

I have a same problem. I've solved it. Actually I have a duplicate property with the same name in my ViewModel. One Property was in BaseViewModel and another is in derived Model.

For Example

public class BaseviewModel{
  public int UserId { get; set; }
}


 public class Model : BaseViewModel
 {
     public int UserId { get; set; }
 }

I have changed them as

  public class BaseviewModel{
     public int UserId { get; set; }
  }


  public class Model : BaseViewModel
  {
      public int User_Id { get; set; }
  }

Now it is working fine.

Upvotes: 2

ErikHeemskerk
ErikHeemskerk

Reputation: 1701

LINQ maintains a 'cache' of sorts of tables you have already used, to prevent having to look them up multiple times.

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

The table you're trying to use hasn't been used within the data context before, so it's being added to the 'cache'. One of the ways this could fail is if you're calling GetTable() from multiple threads simultaneously, which suggests you're using a single data context for the entire application, which is not a good idea. Also, don't use the same data context if you're executing tasks in parallel.

Upvotes: 11

Zeus
Zeus

Reputation: 3357

We have had similar problems after couple of months of deployment in production server. After doing some research I found out that sometimes there is a problem with LINQ closing connection automatically. Now we are specifically closing all the LINQ TO SQL connection via static extension method. Sample code:

public static void extClose(this System.Data.Linq.DataContext dataContext, bool submitChanges)
{
    if (null != dataContext && System.Data.ConnectionState.Closed != dataContext.Connection.State)
    {
        if (true == submitChanges)
        {
            dataContext.SubmitChanges();
        }
        dataContext.Connection.Close();
    }
}

Upvotes: 0

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93551

I had the same error but the cause was one of my many-to-one relationships being defined with the wrong ends as the primary and secondary keys in the relationship.

Using the SQL Server Management Studio designer it was too easy to drag-drop from the child table to the parent table and miss the difference in the created relationship.

Check that all your relationships are correctly defined.

Upvotes: 0

Matt Griffiths
Matt Griffiths

Reputation: 1142

It looks like a bug - but MS have fixed it for .NET 4

http://connect.microsoft.com/VisualStudio/feedback/details/496178/linq-to-sql-projection-throws-argumentexception-an-item-with-the-same-key-has-already-been-added

Are you overriding any properties in your model classes?

Hope this helps,

Matt

Upvotes: 1

Related Questions