An item with the same key has already been added

12,497

Solution 1

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.

Solution 2

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.

Solution 3

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

Share:
12,497

Related videos on Youtube

Tassadaque
Author by

Tassadaque

.....

Updated on June 04, 2022

Comments

  • Tassadaque
    Tassadaque almost 2 years

    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;
                    }
    
                }
            }
        }
    
  • Tassadaque
    Tassadaque about 12 years
    I shifted my application to EF but could u provide some reference some best practice about how the use of datacontext.
  • ErikHeemskerk
    ErikHeemskerk about 12 years
    @Tassadaque I haven't had enough experience with EF, but I think the same guidelines apply: - Don't let more than one thread access the data context simultaneously. - Use a new data context for every work item (be that a request, command from the UI, etc.).
  • Tassadaque
    Tassadaque about 12 years
    if I instantiate datacontext in each repository mycontainer context = new mycontainer(); then more than one thread will not be able to access the datacontext AM I right?. I am having all the access to database through repositories
  • ErikHeemskerk
    ErikHeemskerk about 12 years
    Unless more than one thread accesses the same repository instance. If I haven't made it clear in the previous comment, it's fine for multiple threads to access the same data context class, just not the same instance. If two threads access the same repository instance, they will also access the same data context instance.