2011-08-08 49 views
8

Recibo este error al azar en el servidor de producción, aquí está el rastro de pila del error. Estoy utilizando linq a sql y .net 4.0Ya se ha agregado un elemento con la misma clave

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) 

El código en la línea 14 está debajo. También he incluido el 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; 
    } 

Código en la línea 44 es

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

Por favor, comparta el código de la línea mencionada en el seguimiento de la pila de excepciones –

+0

Qustion actualizado. Por favor, vea el código para la línea 14 similar es el código en otra ubicación – Tassadaque

Respuesta

0

que tenía el mismo error, pero la causa fue una de mis relaciones muchos-a-uno que se define con los extremos equivocadas como las claves primarias y secundarias de la relación .

Al usar el diseñador de SQL Server Management Studio fue demasiado fácil arrastrar y colocar desde la tabla secundaria a la tabla principal y perder la diferencia en la relación creada.

Compruebe que todas sus relaciones estén definidas correctamente.

0

Hemos tenido problemas similares después de algunos meses de implementación en el servidor de producción. Después de investigar, descubrí que a veces hay un problema con la conexión de cierre LINQ automáticamente. Ahora estamos cerrando específicamente toda la conexión LINQ TO SQL a través del método de extensión estática. Código de ejemplo:

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 mantiene un 'caché' de tipo de tablas ya ha utilizado, para evitar tener que mirar hacia arriba varias veces.

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

La tabla que está intentando utilizar no se ha utilizado en el contexto de datos antes, por lo que está siendo añadido a la 'caché'. Una de las formas en que esto podría fallar es si está llamando al GetTable() desde varios subprocesos simultáneamente, lo que sugiere que está utilizando un único contexto de datos para toda la aplicación, lo cual no es una buena idea. Además, no use el mismo contexto de datos si está ejecutando tareas en paralelo.

+1

Cambié mi aplicación a EF pero podría proporcionar alguna referencia sobre las mejores prácticas sobre el uso del contexto de datos. – Tassadaque

+0

@Tassadaque No he tenido suficiente experiencia con EF, pero creo que se aplican las mismas pautas: - No permita que más de un subproceso acceda simultáneamente al contexto de datos. - Utilice un nuevo contexto de datos para cada elemento de trabajo (ya sea una solicitud, un comando de la interfaz de usuario, etc.). – ErikHeemskerk

+0

si instancia el contexto de datos en cada repositorio mycontainer context = new mycontainer(); luego, más de un hilo no podrá acceder al contexto de datos AM I right? Tengo todo el acceso a la base de datos a través de los repositorios – Tassadaque

2

Tengo el mismo problema. Lo he resuelto En realidad, tengo una propiedad duplicada con el mismo nombre en mi ViewModel. Una propiedad estaba en BaseViewModel y otra en Modelo derivado.

Por ejemplo

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


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

que ellos han cambiado como

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


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

Ahora se está trabajando muy bien.

0

Tengo el mismo problema en EF 4.1. con una aplicación existente. ¿Qué pasó? El EF 4.1 requiere .NET Framework 4.0. La actualización de Windows reemplazó el .NET Framework 4.0 con 4.5 y obtuve el mismo error que obtuviste. La solución fue desinstalar .net 4.5 e instalar .net 4.0. En la máquina de producción, debe configurar las ventanas para omitir la actualización a 4.5.

Cuestiones relacionadas