C# 已添加具有相同密钥的项-仅处于释放模式

C# 已添加具有相同密钥的项-仅处于释放模式,c#,.net,entity-framework,release,C#,.net,Entity Framework,Release,专家们 在运行时第一次使用实体框架函数时,我就得到了这个系统.ArgumentException(已经添加了一个具有相同键的项)。 奇怪的是:如果我使用调试模式,它可以正常工作。在编译相同的代码而不在发布模式中进行任何更改后,它立即崩溃,本文顶部提到了一个例外 有人对这种奇怪的行为了解得更多吗?我怎样才能修好它?我无法向我的客户推出调试版本:( 此时将引发异常: try { var blub = context.ExecuteStoreQuery<int>(QueryString

专家们

在运行时第一次使用实体框架函数时,我就得到了这个系统.ArgumentException(已经添加了一个具有相同键的项)。 奇怪的是:如果我使用调试模式,它可以正常工作。在编译相同的代码而不在发布模式中进行任何更改后,它立即崩溃,本文顶部提到了一个例外

有人对这种奇怪的行为了解得更多吗?我怎样才能修好它?我无法向我的客户推出调试版本:(

此时将引发异常:

try
{
  var blub = context.ExecuteStoreQuery<int>(QueryString);
}
catch (Exception ex)
{
  // ...
}    

首先,确保即使生成了干净的发布版本,也会出现错误(我的意思是在运行版本之前没有二进制文件,只有源代码)。如果没有,请修复项目设置(例如,隔离调试和发布版本目标文件夹)

如果错误只发生一次,并且在应用程序正常运行之后,您一定会遇到一些同步问题。虽然这很奇怪,因为元数据加载似乎是同步的。但在任何情况下,EF对象都不是线程安全的。不要在跨线程场景中使用它们

如果上面所说的没有帮助,那么我的研究结果可能会对您有所帮助。以下是与错误相关的EF源代码摘录:

//---------------------------------------------------------------------- 
// <copyright file="ObjectItemAttributeAssemblyLoader.cs" company="Microsoft">
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Objects.DataClasses;
using System.Diagnostics; 
using System.Reflection;

namespace System.Data.Metadata.Edm 
{
  /// <summary> 
  /// Class for representing a collection of items for the object layer.
  /// Most of the implemetation for actual maintainance of the collection is
  /// done by ItemCollection
  /// </summary> 
  internal sealed class ObjectItemAttributeAssemblyLoader :
      ObjectItemAssemblyLoader
  { 
    // ...

    /// <summary>
    /// This method loads all the relationship type that this entity takes part in
    /// </summary> 
    /// <param name="entityType"></param>
    /// <param name="context"></param> 
    private void LoadRelationshipTypes() 
    {
      foreach (EdmRelationshipAttribute roleAttribute in
               SourceAssembly.GetCustomAttributes(typeof(EdmRelationshipAttribute), false /*inherit*/)) 
      {
        // Check if there is an entry already with this name
        if (TryFindNullParametersInRelationshipAttribute(roleAttribute))
        { 
          // don't give more errors for these same bad parameters
          continue; 
        } 

        bool errorEncountered = false; 

        // return error if the role names are the same
        if (roleAttribute.Role1Name == roleAttribute.Role2Name)
        { 
          SessionData.EdmItemErrors.Add(new EdmItemError(
              System.Data.Entity.Strings.SameRoleNameOnRelationshipAttribute(roleAttribute.RelationshipName, roleAttribute.Role2Name),
                       null)); 
          errorEncountered = true; 
        }


        if (!errorEncountered)
        {
          AssociationType associationType = new AssociationType(
            roleAttribute.RelationshipName, roleAttribute.RelationshipNamespaceName,
            roleAttribute.IsForeignKey, DataSpace.OSpace); 
          SessionData.TypesInLoading.Add(associationType.FullName, associationType);
          TrackClosure(roleAttribute.Role1Type); 
          TrackClosure(roleAttribute.Role2Type); 

          // prevent lifting of loop vars 
          string r1Name = roleAttribute.Role1Name;
          Type r1Type = roleAttribute.Role1Type;
          RelationshipMultiplicity r1Multiplicity = roleAttribute.Role1Multiplicity;
          AddTypeResolver(() => 
            ResolveAssociationEnd(associationType, r1Name, r1Type, r1Multiplicity));

          // prevent lifting of loop vars 
          string r2Name = roleAttribute.Role2Name;
          Type r2Type = roleAttribute.Role2Type; 
          RelationshipMultiplicity r2Multiplicity = roleAttribute.Role2Multiplicity;
          AddTypeResolver(() =>
            ResolveAssociationEnd(associationType, r2Name, r2Type, r2Multiplicity));

          // get assembly entry and add association type to the list of types in the assembly
          Debug.Assert(!CacheEntry.ContainsType(associationType.FullName), "Relationship type must not be present in the list of types"); 
          CacheEntry.TypesInAssembly.Add(associationType); 
        }
      } 
    }

    // ...
  }
}
/--------------------------------------------------------------
// 
//版权所有(c)微软公司。保留所有权利。
// 
// 
//@owner[…]
//@backupOwner[…]
//--------------------------------------------------------------------- 
使用System.Collections.Generic;
使用System.Data.Entity;
使用System.Data.Objects.DataClass;
使用系统诊断;
运用系统反思;
命名空间System.Data.Metadata.Edm
{
///  
///类,用于表示对象层的项集合。
///对集合的实际维护的大部分实现是
///由ItemCollection完成
///  
内部密封类ObjectItemAttributeAssemblyLoader:
ObjectItemAssemblyLoader
{ 
// ...
/// 
///此方法加载此实体参与的所有关系类型
///  
/// 
///  
私有void LoadRelationshipTypes()
{
中的foreach(EdmRelationshipAttribute角色属性
SourceAssembly.GetCustomAttributes(typeof(EdmRelationshipAttribute),false/*inherit*/)
{
//检查是否已有具有此名称的条目
if(tryFindNullParametersRelationshipAttribute(角色属性))
{ 
//不要为这些相同的错误参数提供更多错误
继续;
} 
bool errormeeting=false;
//如果角色名称相同,则返回错误
if(roleAttribute.Role1Name==roleAttribute.Role2Name)
{ 
SessionData.EdmItemErrors.Add(新建EdmItemError(
System.Data.Entity.Strings.SameRoleNameOnRelationshipAttribute(roleAttribute.RelationshipName,roleAttribute.Role2Name),
空);
遇到的错误=真;
}
如果(!遇到错误)
{
AssociationType AssociationType=新AssociationType(
roleAttribute.RelationshipName,roleAttribute.RelationshipNamespaceName,
roleAttribute.IsForeignKey,DataSpace.OSpace);
SessionData.TypesInLoading.Add(associationType.FullName,associationType);
轨道闭合(roleAttribute.Role1Type);
轨道闭合(roleAttribute.Role2Type);
//防止吊起回路变压器
字符串r1Name=roleAttribute.RoleName;
类型r1Type=roleAttribute.Role1Type;
RelationshipMultiplicity r1Multiplicity=roleAttribute.Role1Multiplicity;
AddTypeResolver(()=>
ResolveAssociationEnd(associationType,r1Name,r1Type,r1Multiplicity));
//防止吊起回路变压器
字符串r2Name=roleAttribute.Role2Name;
类型r2Type=roleAttribute.Role2Type;
RelationshipMultiplicity r2 Multiplicity=roleAttribute.Role2Multiplicity;
AddTypeResolver(()=>
ResolveAssociationEnd(associationType,r2Name,r2Type,r2Multiplicity));
//获取程序集条目并将关联类型添加到程序集中的类型列表中
Assert(!CacheEntry.ContainsType(associationType.FullName),“关系类型不能出现在类型列表中”);
CacheEntry.TypesInAssembly.Add(associationType);
}
} 
}
// ...
}
}
该方法中使用的唯一字典是
SessionData.TypesInLoading
。该键是
RelationshipName
RelationshipNamespaceName
的组合。有趣的是,一条注释说它们检查重复的键,但该方法
TryFindNullParametersInRelationshipAttribute
只检查该键属性的属性不是
null
s。我想这是一个bug

但更重要的是,所描述的错误一定发生了,因为在程序集中的某个位置,您有多个
EdmRelationshipAttribute
,并且
RelationshipName
RelationshipNamespaceName
属性的组合相等。可能有多种原因:

  • 不正确的EDMX文件
  • 意外复制的程序集
  • 发布配置,将其生成结果输出到与调试配置相同的文件夹
  • 手动生成EF映射程序集时出错
  • 等等
  • 不幸的是,捕获已断开关系的名称将非常困难。您可能必须在
    System.Data.Metadata.Edm.ObjectItemAttributeAsemblyLoader.LoadRelationshipTypes()处设置断点
    并在反汇编中跟踪它。我认为这几乎是不可能的,因为
    Dictionary.Insert
    方法即将
    //---------------------------------------------------------------------- 
    // <copyright file="ObjectItemAttributeAssemblyLoader.cs" company="Microsoft">
    //      Copyright (c) Microsoft Corporation.  All rights reserved.
    // </copyright>
    // 
    // @owner       [....]
    // @backupOwner [....] 
    //--------------------------------------------------------------------- 
    
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Objects.DataClasses;
    using System.Diagnostics; 
    using System.Reflection;
    
    namespace System.Data.Metadata.Edm 
    {
      /// <summary> 
      /// Class for representing a collection of items for the object layer.
      /// Most of the implemetation for actual maintainance of the collection is
      /// done by ItemCollection
      /// </summary> 
      internal sealed class ObjectItemAttributeAssemblyLoader :
          ObjectItemAssemblyLoader
      { 
        // ...
    
        /// <summary>
        /// This method loads all the relationship type that this entity takes part in
        /// </summary> 
        /// <param name="entityType"></param>
        /// <param name="context"></param> 
        private void LoadRelationshipTypes() 
        {
          foreach (EdmRelationshipAttribute roleAttribute in
                   SourceAssembly.GetCustomAttributes(typeof(EdmRelationshipAttribute), false /*inherit*/)) 
          {
            // Check if there is an entry already with this name
            if (TryFindNullParametersInRelationshipAttribute(roleAttribute))
            { 
              // don't give more errors for these same bad parameters
              continue; 
            } 
    
            bool errorEncountered = false; 
    
            // return error if the role names are the same
            if (roleAttribute.Role1Name == roleAttribute.Role2Name)
            { 
              SessionData.EdmItemErrors.Add(new EdmItemError(
                  System.Data.Entity.Strings.SameRoleNameOnRelationshipAttribute(roleAttribute.RelationshipName, roleAttribute.Role2Name),
                           null)); 
              errorEncountered = true; 
            }
    
    
            if (!errorEncountered)
            {
              AssociationType associationType = new AssociationType(
                roleAttribute.RelationshipName, roleAttribute.RelationshipNamespaceName,
                roleAttribute.IsForeignKey, DataSpace.OSpace); 
              SessionData.TypesInLoading.Add(associationType.FullName, associationType);
              TrackClosure(roleAttribute.Role1Type); 
              TrackClosure(roleAttribute.Role2Type); 
    
              // prevent lifting of loop vars 
              string r1Name = roleAttribute.Role1Name;
              Type r1Type = roleAttribute.Role1Type;
              RelationshipMultiplicity r1Multiplicity = roleAttribute.Role1Multiplicity;
              AddTypeResolver(() => 
                ResolveAssociationEnd(associationType, r1Name, r1Type, r1Multiplicity));
    
              // prevent lifting of loop vars 
              string r2Name = roleAttribute.Role2Name;
              Type r2Type = roleAttribute.Role2Type; 
              RelationshipMultiplicity r2Multiplicity = roleAttribute.Role2Multiplicity;
              AddTypeResolver(() =>
                ResolveAssociationEnd(associationType, r2Name, r2Type, r2Multiplicity));
    
              // get assembly entry and add association type to the list of types in the assembly
              Debug.Assert(!CacheEntry.ContainsType(associationType.FullName), "Relationship type must not be present in the list of types"); 
              CacheEntry.TypesInAssembly.Add(associationType); 
            }
          } 
        }
    
        // ...
      }
    }