あなたの(重要な!)コメントを引用します:
メソッドに送信するオブジェクトは添付され、EntityState は Unchanged です。私の DbContext の構成は、AutoDetectChangesEnabled を無効にしたことです...
したがって、コードは次のようになります。
DbContext.Configuration.AutoDetectChangesEnabled = false;
DbContext.Entry(myobj).State = EntityState.Unchanged;
foreach (OtherObj otherObj in otherObjList)
DbContext.Entry(otherObj).State = EntityState.Unchanged;
// entering MyObj_Save method here
foreach (OtherObj otherObj in otherObjList)
{
//DbContext.OtherObj.Attach(otherObj); // does not have an effect
myobj.OtherObj.Add(otherObj);
}
DbContext.Entry(myobj).State = EntityState.Added;
DbContext.SaveChanges();
自動変更検出を無効にしているため、行内myobj
の と のリストの関係が変更されたことに EF が気付かないため、これは実際には機能しません。したがって、エントリは結合テーブルに書き込まれません。保存されるのは自分だけです。OtherObj
myobj.OtherObj.Add(otherObj);
myobj
ここで重要なのはエンティティの状態ではなく、関係の状態であるため、状態マネージャーを関係が保存されている状態にするために、エンティティに状態を設定することはできません。これらは、オブジェクト状態マネージャーの個別のエントリであり、変更検出によって作成および維持されます。
私は3つの解決策を見ます:
設定DbContext.Configuration.AutoDetectChangesEnabled = true;
DetectChanges
手動で呼び出す:
//...
DbContext.Entry(myobj).State = EntityState.Added;
DbContext.ChangeTracker.DetectChanges();
DbContext.SaveChanges();
myobj
状態に設定する前に、コンテキストからnew を切り離しますAdded
(これは私には非常にハッキリしています)。
// entering MyObj_Save method here
DbContext.Entry(myobj).State = EntityState.Detached;
foreach (OtherObj otherObj in otherObjList)
//...
ObjectContext
オブジェクト状態マネージャーの関係エントリを手動で変更することは可能かもしれIObjectContextAdapter
ませんが、その方法はわかりません。
私の意見では、エンティティ (および関係) の状態を手動で操作するこの手順は、EF を操作する方法ではありません。AutoDetectChangesEnabled
EF での作業をより簡単かつ安全にするために導入されました。これを無効にする唯一の推奨される状況は、高パフォーマンス要件 (たとえば、一括挿入) です。自動変更検出を必要なく無効にすると、このような検出が困難な問題が発生し、これらのバグを修正するには EF の内部動作に関する高度な知識が必要になります。