2016-09-14 4 views
0

私は、他の複数のエンティティを熱心に読み込んだ2つの分離エンティティを持っています。 (1対nの関係)。エンティティフレームワークのアタッチ参照先エンティティの自動再帰的なアタッチによる例外

離散したエンティティ(ICollectionナビゲーションプロパティに格納されている)を参照する熱心に読み込まれたエンティティは、2つの分離エンティティの両方に存在できます。

デタッチされたエンティティを両方とも添付したい場合、熱心に読み込まれたエンティティが既に添付されているため、例外が発生します。

これは、問題を説明するコメントを有する典型的なコードです:

public ProvokeAttachException() 
{ 
    //s1 and s2 share some of their samples 
    sample_set s1 = GetSampleSet(1); 
    sample_set s2 = GetSampleSet(2); 

    //Do some stuff 

    //Attaching the sample_sets again 
    using(StationContext context = new StationContext()) 
    { 
     // Fine 
     context.sample_set.Attach(s1); 

     //Throws Exception because some of the included samples in sample_set 
     //have been attached automatically with s1 
     context.sample_set.Attach(s2); 
    } 

} 

public sample_set GetSampleSet(int setId) 
{ 
    //Eager Loading all samples that reference sample_set (1 to n relation) 
    using (StationContext context = new StationContext()) 
    { 
     return context.sample_set.Include("sample").FirstOrDefault(s => s.id = setId); 
    } 
} 

私は例外なく両方のエンティティを添付できますか?

+0

データモデリングに関する詳細情報を提供してください。あなたはそれでいくつかのリファクタリングをする必要があるかもしれません。オブジェクトがすでにアタッチされている場合は、再度アタッチすることはできません。 – PedroSouki

+0

@PedroSoukiエンティティをもう一度付けることはできません。私は新しい文脈を持っており、s1とs2を付けることが私が最​​初に行うことなので、すでに取り付けることはできません。それは熱心に読み込まれ、それらのいくつかはs1とs2によって共有される「サンプル」エンティティのためです。 Attachは、ナビゲーションプロパティに含まれるすべての参照エンティティを再帰的かつ自動的に添付します。私はどのように例外を避けることができ、s1とs2に含まれるすべてのエンティティがアタッチされるのか分かりません –

答えて

0

問題は付属品ですので、代わりにAddを使用してください。

context.sample_set.Attach(s1);を実行するときは、実際には、新しいコンテキスト内のすべての関連オブジェクトのインスタンスを作成し、それをsample_setに追加して、なぜ動作させるのかを確認します。

context.sample_set.Attach(s2);を実行しようとすると、すべての共有者samplesを再度作成しようとします。そのため、例外がスローされます。

だから、あなたに私の提案は次のとおりです。

context.sample_set.Add(s1); 
context.sample_set.Add(s2); 
context.SaveChanges(); 

私はそれが役に立てば幸い。

+0

あなたの答えをありがとう!しかし、追加はデータベースに新しいエントリを追加/挿入するためのものです。 s1とs2はデータベース内に存在し、コンテキストから切り離され、再度接続する必要があります。すべての共有サンプルおよび非共有サンプルは、すでにデータベースに存在しています。だから、私は簡単に必要があります。添付しないでください。 –

+0

私はエンティティを切り離す必要がある理由を理解していません。編集だけでデータを取得したい場合は、変更内容に 'context.Entry(obj).State = EntityState.Modified;とSaveChangesを設定します。 – PedroSouki

+0

Attachを使用する一般的な理由は、エンティティを再度取得する必要がなく、 dbから検索されたように使用でき、データベーストランザクションは必要ありません。例えば。添付されたエンティティをデタッチしたエンティティでワイヤリングするとNavigationPropertiesが機能しません –

関連する問題