2012-04-18 10 views
2

専門家、同じキーを持つ項目が既に追加されている - ただ、リリースモードで

私がこのSystem.ArgumentExceptionの同じキーを持つ項目が既にを追加されている)を取得しています実行時にエンティティフレームワーク関数を最初に使用する。 奇妙なこと:私がデバッグモードを使用している場合、正常に動作します。 リリースモードで変更を加えずに同じコードをコンパイルすると、このポストの先頭に記載されている例外を除いて即座にクラッシュします。

誰でもこのような奇妙な動作について知っていますか?どうすれば修正できますか?私は私の顧客にデバッグバージョンをロールアウトすることができません:(

例外は、この時点でスローされます。

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

スタックトレース:

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) 
+0

EFのどのバージョンとフレーバー(POCO、コードファーストなど)を使用しますか? –

+0

スタックトレースにはさらに情報が必要です。おそらく何かを切ったことがありますか? –

+0

は、既存のmssqlデータベースからモデルを作成したばかりです。ポコはありません。 – Machine

答えて

2

まず、場合でも、あなたがエラーを取得することを確認しますクリーンリリースビルド(ビルドを実行する前にバイナリがないこと、つまりソースコードのみを意味する)を作成します。そうでない場合は、プロジェクトセットアップを修正します(例えば、デバッグとビルドターゲットフォルダの隔離)。

エラーが1回しか発生しない場合は、アプリが正常に動作する場合は、同期の問題が発生している必要があります。メタデータの読み込みは同期しているように見えるので、非常に奇妙です。しかし、いずれの場合でも、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); 
     } 
     } 
    } 

    // ... 
    } 
} 

方法で使用される唯一の辞書SessionData.TypesInLoadingあります。キーはRelationshipNameRelationshipNamespaceNameの組み合わせです。面白いのは、重複したキーがあるかどうかを確認するというコメントがありますが、方法TryFindNullParametersInRelationshipAttributeは、属性のプロパティがnullではないことのみをチェックします。私はそれがバグだと思う。

しかし、もっと重要なのは、どこかのアセンブリであなたがRelationshipNameRelationshipNamespaceNameプロパティの同じ組み合わせで複数のEdmRelationshipAttributeを持っているので、説明エラーが発生していなければならないということです。さまざまな理由が考えられます。

  1. 不正なEDMXファイル。
  2. Impropperlyコピーアセンブリなど、それはデバッグ構成と同じフォルダに結果を構築するのですoutputing
  3. リリース構成、EFマッピングアセンブリのマニュアル世代で
  4. エラー、
残念ながら

、キャッチ壊れた関係の名前は非常に難しいでしょう。おそらく、ブレークポイントをSystem.Data.Metadata.Edm.ObjectItemAttributeAssemblyLoader.LoadRelationshipTypes()に設定し、それを逆アセンブリでトレースする必要があります。 Dictionary.Insertメソッドがと多く呼ばれようとしているので、ほとんど不可能になると私は言うだろう。回。

これらすべてが解決策を示唆していない場合は、問題の解決策を準備してここに投稿する必要があります。そうしないと、誰も手助けできなくなります。

+0

昨日の夕方、私は、ExecuteStoreQueryが例外を引き起こしていることを知っていました。なぜなら、edmxやアセンブリには何の問題もありません。:/ – Machine

関連する問題