2011-08-08 17 views
8

Otrzymuję ten błąd losowo na serwerze produkcyjnym tutaj jest ślad stosu błędu. Używam linq do sql i .net 4.0Produkt z tym samym kluczem został już dodany

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) 

Kod w linii 14 znajduje się poniżej. Mam również 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; 
    } 

Kod na linii 44 jest

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; 
       } 

      } 
     } 
    } 
+0

Proszę udostępnić kod z wiersza wymienionego w zestawieniu wyjątków stosu –

+0

Qustion updated. Proszę zobaczyć kod dla linii 14 podobnie jest kod w innej lokalizacji – Tassadaque

Odpowiedz

0

Miałem ten sam błąd, ale przyczyną był jeden z moich relacji wiele-do-jednego są zdefiniowane z niewłaściwymi końcach jak pierwotne i wtórne kluczy w relacji .

Za pomocą projektanta SQL Server Management Studio zbyt łatwo przeciągnąć kroplę z tabeli podrzędnej do tabeli nadrzędnej i pominąć różnicę w utworzonej relacji.

Sprawdź, czy wszystkie relacje są poprawnie zdefiniowane.

0

Po kilku miesiącach wdrażania na serwerze produkcyjnym mieliśmy podobne problemy. Po przeprowadzeniu badań odkryłem, że czasami jest problem z automatycznym zamykaniem połączenia LINQ. Teraz zamykamy wszystkie połączenia LINQ TO SQL za pomocą metody statycznego rozszerzenia. Przykładowy kod:

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(); 
    } 
} 
8

LINQ utrzymuje „cache” sortuje tabel już stosowane, aby zapobiec konieczności zaglądania je wielokrotnie.

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

Tabela, której próbujesz użyć, nie była wcześniej używana w kontekście danych, więc jest dodawana do "pamięci podręcznej". Jednym ze sposobów, w jaki może to się nie powieść, jest wywoływanie GetTable() z wielu wątków jednocześnie, co sugeruje, że używasz pojedynczego kontekstu danych dla całej aplikacji, co nie jest dobrym pomysłem. Nie używaj tego samego kontekstu danych, jeśli wykonujesz zadania równolegle.

+1

Przesunąłem moją aplikację do EF, ale mógłbym podać kilka referencji najlepszych praktyk dotyczących sposobu korzystania z datacontext. – Tassadaque

+0

@ Tassadaque Nie miałem wystarczającego doświadczenia z EF, ale myślę, że te same wytyczne mają zastosowanie: - Nie pozwól, aby więcej niż jeden wątek miał dostęp do kontekstu danych jednocześnie. - Użyj nowego kontekstu danych dla każdego elementu pracy (czy to żądania, polecenie z interfejsu itp.). – ErikHeemskerk

+0

jeśli utworzę datacontext w każdym kontekście mycontainer repozytorium = new mycontainer(); następnie więcej niż jeden wątek nie będzie w stanie uzyskać dostępu do datacontext AM I right ?. Mam cały dostęp do bazy danych za pośrednictwem repozytoriów – Tassadaque

2

Mam ten sam problem. Rozwiązałem to. W rzeczywistości mam duplikat właściwości o tej samej nazwie w moim ViewModel. Jedna właściwość była w BaseViewModel, a druga w modelu pochodnym.

Dla przykładu

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


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

Zmieniłem je jako

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


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

Teraz pracuje bez zarzutu.

0

Mam ten sam problem w EF 4.1. z istniejącą aplikacją. Co się stało? EF 4.1 wymaga platformy .net 4.0. Aktualizacja systemu Windows zastąpiła platformę .net 4.0 z 4.5 i otrzymałem ten sam błąd, który otrzymałeś. Rozwiązaniem było odinstalowanie .net 4.5 i instalacja .net 4.0. Na maszynie produkcyjnej powinieneś ustawić okna, aby pominąć aktualizację do wersji 4.5.

Powiązane problemy