In Release mode, an item with the same key has already been added.

.net c# entity-framework release

Question

Experts,

When I utilize an entity framework function for the very first time during runtime, I get this System.ArgumentException (The identical item has already been added using the same key.). The odd thing is that it functions normally when I use debug mode. When the identical code is compiled in launch mode without any modifications, it immediately crashes with the exception indicated at the start of this article.

Does anybody have further information on this peculiar behavior? How do I correct it? I am unable to provide a debug version to my client: (

This is when an exception is raised:

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

Stacktrace:

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, Boo
lean add)
   at System.Data.Metadata.Edm.ObjectItemAttributeAssemblyLoader.LoadRelationshi
pTypes()
   at System.Data.Metadata.Edm.ObjectItemAttributeAssemblyLoader.LoadTypesFromAs
sembly()
   at System.Data.Metadata.Edm.ObjectItemAssemblyLoader.Load()
   at System.Data.Metadata.Edm.ObjectItemAttributeAssemblyLoader.Load()
   at System.Data.Metadata.Edm.AssemblyCache.LoadAssembly(Assembly assembly, Boo
lean loadReferencedAssemblies, ObjectItemLoadingSessionData loadingData)
   at System.Data.Metadata.Edm.AssemblyCache.LoadAssembly(Assembly assembly, Boo
lean loadReferencedAssemblies, ObjectItemLoadingSessionData loadingData)
   at System.Data.Metadata.Edm.AssemblyCache.LoadAssembly(Assembly assembly, Boo
lean loadReferencedAssemblies, ObjectItemLoadingSessionData loadingData)
   at System.Data.Metadata.Edm.AssemblyCache.LoadAssembly(Assembly assembly, Boo
lean loadReferencedAssemblies, ObjectItemLoadingSessionData loadingData)
   at System.Data.Metadata.Edm.AssemblyCache.LoadAssembly(Assembly assembly, Boo
lean loadReferencedAssemblies, KnownAssembliesSet knownAssemblies, EdmItemCollec
tion edmItemCollection, Action`1 logLoadMessage, Object& loaderCookie, Dictionar
y`2& typesInLoading, List`1& errors)
   at System.Data.Metadata.Edm.ObjectItemCollection.LoadAssemblyFromCache(Object
ItemCollection objectItemCollection, Assembly assembly, Boolean loadReferencedAs
semblies, EdmItemCollection edmItemCollection, Action`1 logLoadMessage)
   at System.Data.Metadata.Edm.MetadataWorkspace.ImplicitLoadAssemblyForType(Typ
e type, Assembly callingAssembly)
   at System.Data.Objects.ObjectContext.ExecuteStoreQueryInternal[TElement](Stri
ng commandText, String entitySetName, MergeOption mergeOption, Object[] paramete
rs)
1
2
4/19/2012 10:41:44 AM

Popular Answer

First, check to see whether you still get the problem if you type pristine release build (I mean no binaries before running the build, source code only). Fix your project configuration if you don't (isolate debug and release build target folders for example).

If the error just happens once and then the program continues to function normally, there must be some synchronization problems. However, it's pretty odd since metadata loading seems to be coordinated. EF objects are not thread-safe, however, in any case. Never use them in cross-thread situations.

If the aforementioned advice is ineffective, maybe the findings of my investigation will be of assistance. An example of the error-related source code from EF is shown below:

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

    // ...
  }
}

The technique uses just one dictionary:SessionData.TypesInLoading The right mix of is the key.RelationshipName and RelationshipNamespaceName . It's ironic that a remark claims they look for duplicate keys, yet the procedureTryFindNullParametersInRelationshipAttribute merely verifies that an attribute's properties are notnull It must be a bug, I guess.

However, the fact that there are several instances of the mentioned problem in your assemblies is more significant.EdmRelationshipAttribute equivalent combinations ofRelationshipName and RelationshipNamespaceName properties. There might be many causes:

  1. erroneous EDMX file
  2. assemblies that were improperly copied,
  3. The build results from Release configuration are exported to the same location as Debug configuration,
  4. error-filled manual EF mapping assembly creation,
  5. etc.

Unfortunately, it will be exceedingly challenging to identify the name of the failed relationship. Most likely, you'll need to set a breakpoint atSystem.Data.Metadata.Edm.ObjectItemAttributeAssemblyLoader.LoadRelationshipTypes() and follow it while disassembling. It will be almost hard, in my opinion, because of theDictionary.Insert The technique is going to get 84 calls in total.

If none of these still point to the answer, you must create a repro of your problem and report it here. If not, no one will be able to assist.

2
4/18/2012 3:06:37 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow