已添加具有相同键的项目

时间:2011-08-08 07:43:35

标签: asp.net asp.net-mvc linq asp.net-mvc-3 linq-to-sql

我在生产服务器上随机获得此错误,这里是错误的堆栈跟踪。我正在使用linq到sql和.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)

第14行的代码如下。我还包括了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;
    }

第44行的代码是

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

            }
        }
    }

6 个答案:

答案 0 :(得分:8)

LINQ维护您已经使用的各种表的“缓存”,以防止多次查找它们。

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

您之前尝试使用的表尚未在数据上下文中使用,因此将其添加到“缓存”中。如果您同时从多个线程调用GetTable(),这可能会失败的方法之一就是建议您为整个应用程序使用单个数据上下文,这不是一个好主意。另外,如果您并行执行任务,请不要使用相同的数据上下文。

答案 1 :(得分:2)

我有同样的问题。我已经解决了。 实际上我在ViewModel中有一个具有相同名称的重复属性。 一个属性位于BaseViewModel中,另一个位于派生模型中。

例如

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


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

我已将其更改为

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


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

现在工作正常。

答案 2 :(得分:1)

它看起来像一个错误 - 但是MS已经为.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

您是否覆盖模型类中的任何属性?

希望这有帮助,

马特

答案 3 :(得分:0)

我遇到了同样的错误,但原因是我的多对一关系之一被错误地定义为关系中的主键和辅助键。

使用SQL Server Management Studio设计器很容易从子表拖放到父表,并且错过了创建的关系中的差异。

检查您的所有关系是否都已正确定义。

答案 4 :(得分:0)

在生产服务器中部署几个月后,我们遇到了类似的问题。在做了一些研究后,我发现有时LINQ关闭连接会自动出现问题。现在我们通过静态扩展方法专门关闭所有LINQ TO SQL连接。示例代码:

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

答案 5 :(得分:0)

我在EF 4.1中遇到了同样的问题。与现有的应用程序。 发生了什么? EF 4.1需要.net framework 4.0。 Windows更新用4.5取代了.net framework 4.0,我得到了同样的错误。 解决方案是卸载.net 4.5并安装.net 4.0。 在生产机器上,您应该将窗口设置为跳过更新到4.5。